

var s_account = "nihncbiprod";

(function(){
    
    if (document.cookie.length>0){
        var c_start=document.cookie.indexOf("NCBISTATLOC=");
        if(c_start!=-1){ 
            c_start = c_start + 12; 
            var c_end = document.cookie.indexOf(";",c_start);
            if (c_end==-1) c_end = document.cookie.length;
            var ckVal = document.cookie.substring(c_start,c_end);
            if(ckVal.length>0) s_account=ckVal;
        } 
    }
    
})();



/* SiteCatalyst code version: H.19.3.
Copyright 1997-2009 Omniture, Inc. More info available at
http://www.omniture.com */
/************************ ADDITIONAL FEATURES ************************
     Plugins
*/


var s=s_gi(s_account)
/************************** CONFIG SECTION **************************/
/* You may add or alter any code config here. */
/* Specify the life time of the cookie in seconds, or */
/* set to "Session" to turn off persistent cookies.   */
s.cookieLifetime="Session"
/* Conversion Config */
s.currencyCode="USD"
/* Link Tracking Config */
s.trackDownloadLinks=true
s.trackExternalLinks=true
s.trackInlineStats=true
s.linkDownloadFileTypes="exe,zip,wav,mp3,mov,mpg,avi,wmv,pdf,doc,docx,xls,xlsx,ppt,pptx"
s.linkInternalFilters="javascript:,ncbi.nlm.nih.gov"
s.linkLeaveQueryString=false
s.linkTrackVars="None"
s.linkTrackEvents="None"
/* Plugin Config */
s.usePlugins=true

/* Page Name Plugin Config */
s.siteID=""            // leftmost value in pagename
s.defaultPage=""       // filename to add when none exists
s.queryVarsList=""     // query parameters to keep
s.pathExcludeDelim=";" // portion of the path to exclude
s.pathConcatDelim=""   // page name component separator
s.pathExcludeList=""   // elements to exclude from the path

function s_doPlugins(s) {
	/* Add calls to plugins here */
	
	/*Populate Page Name*/
	if(!s.pageName && !s.pageType)
		s.pageName=s.getPageName();
	
	/*Track External Campaign*/
	if(!s.campaign)
		s.campaign=s.getQueryParam('psrc');
		s.campaign=s.getValOnce(s.campaign,'s_campaign',0);
	
	/*Page View*/
	s.events=s.apl(s.events,'event2',',',2)
	
	/****************Internal Search****************/
	/*Copy Internal Search Term*/
	if(s.prop3) s.prop3=s.prop3.toLowerCase()
	if(s.prop3){
	    s.eVar3=s.prop3

	/* Set de-duped onsite search event */
	var t_search=s.getValOnce(s.eVar3,'ev3',0)
	if(t_search)
		s.events=s.apl(s.events,'event1',',',1)
	}
	
	/*Copy Search Type*/
	if(s.prop4 && !s.eVar4) s.eVar4 = s.prop4 //Search Type
	
	/***************Entrez Limit**********************/
	/*Copy Limit Criteria Set (Entrez limit) */
	if(s.prop17) s.prop17=s.prop17.toLowerCase()
	if(s.prop17){
	    s.eVar17=s.prop17

	/* Set de-duped onsite search event */
	var t_search=s.getValOnce(s.eVar17,'ev17',0)
	if(t_search)
		s.events=s.apl(s.events,'event7',',',1)
	}
	
	/*Copy Limit Criteria Set Values */
	if(s.prop19) s.prop19=s.prop19.toLowerCase()
	if(s.prop19){
	    s.eVar19=s.prop19

	/* Set de-duped onsite search event */
	var t_search=s.getValOnce(s.eVar19,'ev19',0)
	if(t_search)
		s.events=s.apl(s.events,'event7',',',1)
	}
	
	/******************Advanced Search***************/
	/*Copy Advanced Search Criteria*/
	if(s.prop18) s.prop18=s.prop18.toLowerCase()
	if(s.prop18){
	    s.eVar18=s.prop18

	/* Set de-duped onsite search event */
	var t_search=s.getValOnce(s.eVar18,'ev18',0)
	if(t_search)
		s.events=s.apl(s.events,'event8',',',1)
	}
	
	/*Copy Advanced Search Criteria Values*/
	if(s.prop20) s.prop20=s.prop20.toLowerCase()
	if(s.prop20){
	    s.eVar20=s.prop20

	/* Set de-duped onsite search event */
	var t_search=s.getValOnce(s.eVar20,'ev20',0)
	if(t_search)
		s.events=s.apl(s.events,'event8',',',1)
	}
	
	/***************Entrez Filter Applied**************/
	/*Copy Entrez Filter Applies*/
	if(s.prop38) s.prop38=s.prop38.toLowerCase()
	if(s.prop38){
	    s.eVar38=s.prop38

	/* Set de-duped onsite search event */
	var t_search=s.getValOnce(s.eVar38,'ev38',0)
	if(t_search)
		s.events=s.apl(s.events,'event9',',',1)
	}
	
	/*Time Parting*/
	s.prop34=s.getTimeParting('h','-5','2009'); // Set hour
	s.prop35=s.getTimeParting('d','-5','2009'); // Set day
	s.prop36=s.getTimeParting('w','-5','2009'); // Set Weekend / Weekday
	s.eVar34=s.prop34;
	s.eVar35=s.prop35;
	s.eVar36=s.prop36;
	
	/*Google Scholars tracking*/
	if(document.referrer.indexOf('scholar.google.com') > -1){
		s.eVar32='scholar.google.com';
		s.prop32=s.getAndPersistValue(s.eVar32,'s_dr_persist',0);
		s.prop33=s.prop32+':'+s.pageName;
	}
	
	/*Copy props to eVars*/
	if(s.prop1 && !s.eVar1) s.eVar1 = s.prop1; //Page Hit ID
	if(s.prop2 && !s.eVar2) s.eVar2 = s.prop2; //Database
	if(s.prop5 && !s.eVar5) s.eVar5 = s.prop5; //Search Display(Report Name)
	if(s.prop6 && !s.eVar6) s.eVar6 = s.prop6; //SEarch Show (Page Size)
	if(s.prop7 && !s.eVar7) s.eVar7 = s.prop7; //Search Sort By (Sort Order)
	if(s.prop8 && !s.eVar8) s.eVar8 = s.prop8; //Current Page (Search Page)
	if(s.prop11 && !s.eVar11) s.eVar11 = s.prop11; //Link Name
	if(s.prop12 && !s.eVar12) s.eVar12 = s.prop12; //Database Source
	if(s.prop13 && !s.eVar13) s.eVar13 = s.prop13; //Link Id (TI)
	if(s.prop14 && !s.eVar14) s.eVar14 = s.prop14; //Link Name (TN)
	if(s.prop15 && !s.eVar15) s.eVar15 = s.prop15; //Link Pos (TS)
	if(s.prop16 && !s.eVar16) s.eVar16 = s.prop16; //Entrez Operation
	if(s.prop21 && !s.eVar21) s.eVar21 = s.prop21; //Page Design ID
	if(s.prop22 && !s.eVar22) s.eVar22 = s.prop22; //Session ID
	if(s.prop23 && !s.eVar23) s.eVar23 = s.prop23; //Site Section 2
	if(s.prop24 && !s.eVar24) s.eVar24 = s.prop24; //Sub Section 3
	if(s.prop25 && !s.eVar25) s.eVar25 = s.prop25; //Sub Section 3
	if(s.prop26 && !s.eVar26) s.eVar26 = s.prop26; //Content ID
	if(s.channel && !s.eVar27) s.eVar27 = s.channel; //Site Section
	if(s.pageName && !s.eVar41) s.eVar41 = s.pageName; //Page Name

}
s.doPlugins=s_doPlugins
/************************** PLUGINS SECTION *************************/
/* You may insert any plugins you wish to use here.                 */


/* WARNING: Changing any of the below variables will cause drastic
changes to how your visitor data is collected.  Changes should only be
made when instructed to do so by your account manager.*/
s.visitorNamespace="nih"
s.trackingServer="a.ncbi.nlm.nih.gov"
s.dc=122

/*
 * Plugin: getAndPersistValue 0.3 - get a value on every page
 */
s.getAndPersistValue=new Function("v","c","e",""
+"var s=this,a=new Date;e=e?e:0;a.setTime(a.getTime()+e*86400000);if("
+"v)s.c_w(c,v,e?a:0);return s.c_r(c);");

/*
 * Plugin: getPageName v2.1 - parse URL and return
 */
s.getPageName=new Function("u",""
+"var s=this,v=u?u:''+s.wd.location,x=v.indexOf(':'),y=v.indexOf('/',"
+"x+4),z=v.indexOf('?'),c=s.pathConcatDelim,e=s.pathExcludeDelim,g=s."
+"queryVarsList,d=s.siteID,n=d?d:'',q=z<0?'':v.substring(z+1),p=v.sub"
+"string(y+1,q?z:v.length);z=p.indexOf('#');p=z<0?p:s.fl(p,z);x=e?p.i"
+"ndexOf(e):-1;p=x<0?p:s.fl(p,x);p+=!p||p.charAt(p.length-1)=='/'?s.d"
+"efaultPage:'';y=c?c:'/';while(p){x=p.indexOf('/');x=x<0?p.length:x;"
+"z=s.fl(p,x);if(!s.pt(s.pathExcludeList,',','p_c',z))n+=n?y+z:z;p=p."
+"substring(x+1)}y=c?c:'?';while(g){x=g.indexOf(',');x=x<0?g.length:x"
+";z=s.fl(g,x);z=s.pt(q,'&','p_c',z);if(z){n+=n?y+z:z;y=c?c:'&'}g=g.s"
+"ubstring(x+1)}return n");

/*
 * Utility Function: p_c
 */
s.p_c=new Function("v","c",""
+"var x=v.indexOf('=');return c.toLowerCase()==v.substring(0,x<0?v.le"
+"ngth:x).toLowerCase()?v:0");


/*
 * Utility Function: split v1.5 - split a string (JS 1.0 compatible)
 */
s.split=new Function("l","d",""
+"var i,x=0,a=new Array;while(l){i=l.indexOf(d);i=i>-1?i:l.length;a[x"
+"++]=l.substring(0,i);l=l.substring(i+d.length);}return a");

/*
 * Plugin: getQueryParam 2.3
 */
s.getQueryParam=new Function("p","d","u",""
+"var s=this,v='',i,t;d=d?d:'';u=u?u:(s.pageURL?s.pageURL:s.wd.locati"
+"on);if(u=='f')u=s.gtfs().location;while(p){i=p.indexOf(',');i=i<0?p"
+".length:i;t=s.p_gpv(p.substring(0,i),u+'');if(t){t=t.indexOf('#')>-"
+"1?t.substring(0,t.indexOf('#')):t;}if(t)v+=v?d+t:t;p=p.substring(i="
+"=p.length?i:i+1)}return v");
s.p_gpv=new Function("k","u",""
+"var s=this,v='',i=u.indexOf('?'),q;if(k&&i>-1){q=u.substring(i+1);v"
+"=s.pt(q,'&','p_gvf',k)}return v");
s.p_gvf=new Function("t","k",""
+"if(t){var s=this,i=t.indexOf('='),p=i<0?t:t.substring(0,i),v=i<0?'T"
+"rue':t.substring(i+1);if(p.toLowerCase()==k.toLowerCase())return s."
+"epa(v)}return ''");

/*
* Plugin Utility: apl v1.1
*/
s.apl=new Function("L","v","d","u",""
+"var s=this,m=0;if(!L)L='';if(u){var i,n,a=s.split(L,d);for(i=0;i<a."
+"length;i++){n=a[i];m=m||(u==1?(n==v):(n.toLowerCase()==v.toLowerCas"
+"e()));}}if(!m)L=L?L+d+v:v;return L");

 /* Plugin: getValOnce 0.2 - get a value once per session or number of days
 */
s.getValOnce=new Function("v","c","e",""
+"var s=this,k=s.c_r(c),a=new Date;e=e?e:0;if(v){a.setTime(a.getTime("
+")+e*86400000);s.c_w(c,v,e?a:0);}return v==k?'':v");


/*
 * Function - read combined cookies v 0.2
 */
s.c_rr=s.c_r;
s.c_r=new Function("k",""
+"var s=this,d=new Date,v=s.c_rr(k),c=s.c_rr('s_pers'),i,m,e;if(v)ret"
+"urn v;k=s.ape(k);i=c.indexOf(' '+k+'=');c=i<0?s.c_rr('s_sess'):c;i="
+"c.indexOf(' '+k+'=');m=i<0?i:c.indexOf('|',i);e=i<0?i:c.indexOf(';'"
+",i);m=m>0?m:e;v=i<0?'':s.epa(c.substring(i+2+k.length,m<0?c.length:"
+"m));if(m>0&&m!=e)if(parseInt(c.substring(m+1,e<0?c.length:e))<d.get"
+"Time()){d.setTime(d.getTime()-60000);s.c_w(s.epa(k),'',d);v='';}ret"
+"urn v;");
/*
 * Function - write combined cookies v 0.2
 */
s.c_wr=s.c_w;
s.c_w=new Function("k","v","e",""
+"var s=this,d=new Date,ht=0,pn='s_pers',sn='s_sess',pc=0,sc=0,pv,sv,"
+"c,i,t;d.setTime(d.getTime()-60000);if(s.c_rr(k)) s.c_wr(k,'',d);k=s"
+".ape(k);pv=s.c_rr(pn);i=pv.indexOf(' '+k+'=');if(i>-1){pv=pv.substr"
+"ing(0,i)+pv.substring(pv.indexOf(';',i)+1);pc=1;}sv=s.c_rr(sn);i=sv"
+".indexOf(' '+k+'=');if(i>-1){sv=sv.substring(0,i)+sv.substring(sv.i"
+"ndexOf(';',i)+1);sc=1;}d=new Date;if(e){if(e.getTime()>d.getTime())"
+"{pv+=' '+k+'='+s.ape(v)+'|'+e.getTime()+';';pc=1;}}else{sv+=' '+k+'"
+"='+s.ape(v)+';';sc=1;}if(sc) s.c_wr(sn,sv,0);if(pc){t=pv;while(t&&t"
+".indexOf(';')!=-1){var t1=parseInt(t.substring(t.indexOf('|')+1,t.i"
+"ndexOf(';')));t=t.substring(t.indexOf(';')+1);ht=ht<t1?t1:ht;}d.set"
+"Time(ht);s.c_wr(pn,pv,d);}return v==s.c_r(s.epa(k));");


/*
 * Plugin: getTimeParting 1.4 - Set timeparting values based on time zone (15 min)
 */

s.getTimeParting=new Function("t","z","y",""
+"dc=new Date('1/1/2000');var f=15;var ne=8;if(dc.getDay()!=6||"
+"dc.getMonth()!=0){return'Data Not Available'}else{;z=parseInt(z);"
+"if(y=='2009'){f=8;ne=1};gmar=new Date('3/1/'+y);dsts=f-gmar.getDay("
+");gnov=new Date('11/1/'+y);dste=ne-gnov.getDay();spr=new Date('3/'"
+"+dsts+'/'+y);fl=new Date('11/'+dste+'/'+y);cd=new Date();"
+"if(cd>spr&&cd<fl){z=z+1}else{z=z};utc=cd.getTime()+(cd.getTimezoneO"
+"ffset()*60000);tz=new Date(utc + (3600000*z));thisy=tz.getFullYear("
+");var days=['Sunday','Monday','Tuesday','Wednesday','Thursday','Fr"
+"iday','Saturday'];if(thisy!=y){return'Data Not Available'}else{;thi"
+"sh=tz.getHours();thismin=tz.getMinutes();thisd=tz.getDay();var dow="
+"days[thisd];var ap='AM';var dt='Weekday';var mint='00';if(thismin>1"
+"5&&thismin<30){mint='15'}if(thismin>30&&thismin<45){mint='30'}if(th"
+"ismin>45&&thismin<60){mint='45'}"
+"if(thish>=12){ap='PM';thish=thish-12};if (thish==0){th"
+"ish=12};if(thisd==6||thisd==0){dt='Weekend'};var timestring=thish+'"
+":'+mint+ap;var daystring=dow;var endstring=dt;if(t=='h'){return tim"
+"estring}if(t=='d'){return daystring};if(t=='w'){return en"
+"dstring}}};"
);

/************* DO NOT ALTER ANYTHING BELOW THIS LINE ! **************/
var s_code='',s_objectID;function s_gi(un,pg,ss){var c="=fun^I(~){`Ls=^Z~$w ~.substring(~.indexOf(~;@t~`c@t~=new Fun^I(~.toLowerCase()~};s.~.length~s_c_il['+s@4n+']~=new Object~`aMigrationServer~.toU"
+"pperCase~){@t~`V$x=^O=s.`X`q=s.`X^c=`I^zobjectID=s.ppu=$8=$8v1=$8v2=$8v3=~','~s.wd~t^S~')q='~var ~s.pt(~=new Array~ookieDomainPeriods~.location~^KingServer~dynamicAccount~s.apv~='+#D~BufferedReques"
+"ts~);s.~)@tx^w!Object$pObject.prototype$pObject.prototype[x])~link~s.m_~Element~visitor~referrer~else ~.get#9()~}c#B(e){~.lastIndexOf(~.protocol~=new Date~=''~;@d^ss[k],255)}~javaEnabled~conne^I^c~"
+"^zc_i~:'')~onclick~}@t~Name~ternalFilters~javascript~s.dl~@9s.b.addBehavior(\"# default# ~for(~=parseFloat(~'+tm.get~typeof(v)==\"~window~cookie~s.rep(~s.vl_g~tfs~s.un~&&s.~o^zoid~browser~.parent~d"
+"ocument~colorDepth~String~while(~.host~s.maxDelay~r=s.m(f)?s[f](~s.sq~parseInt(~ction~t=s.ot(o)~track~nload~j='1.~#NURL~s.eo~lugins~'){q='~dynamicVariablePrefix~=='~set#9out(~Sampling~s.rc[un]~Even"
+"t~;i++)~');~this~resolution~}else{~Type~s.c_r(~s.c_w(~s.eh~s.isie~s.vl_l~s.vl_t~Secure~Height~t,h#Wt?t~tcf~isopera~ismac~escape(~.href~screen.~s.fl(~s=s_gi(~Version~harCode~&&(~_'+~variableProvider"
+"~.s_~f',~){s.~)?'Y':'N'~:'';h=h?h~._i~e&&l!='SESSION'~s_sv(v,n[k],i)}~name~home#N~;try{~s.ssl~s.oun~s.rl[u~Width~o.type~\"m_\"+n~Lifetime~s.gg('objectID~sEnabled~.mrq($run+'\"~ExternalLinks~charSet"
+"~onerror~currencyCode~.src~disable~etYear(~MigrationKey~&&!~Opera~'s_~Math.~s.fsg~s.$x~s.ns6~InlineStats~&&l!='NONE'~Track~'0123456789~s[k]=~'+n+'~loadModule~+\"_c\"]~s.epa(~t.m_nl~m._d~n=s.oid(o)~"
+",'sqs',q);~LeaveQuery~(''+~')>=~'=')~){n=~\",''),~&&t!='~if(~vo)~s.sampled~=s.oh(o);~+(y<1900?~n]=~true~sess~campaign~lif~ in ~'http~,100)~s.co(~ffset~s.pe~'&pe~m._l~s.c_d~s.brl~s.nrs~s.gv(~s[mn]~s"
+".qav~,'vo~s.pl~=(apn~Listener~\"s_gs(\")~vo._t~b.attach~2o7.net'~d.create~=s.n.app~n){~t&&~)+'/~s()+'~){p=~():''~a):f(~'+n;~+1))~a['!'+t]~){v=s.n.~channel~.target~x.split~o.value~[\"s_\"+g~s_si(t)~"
+"')dc='1~\".tl(\")~etscape~s_')t=t~omePage~s.d.get~')<~||!~'||~\"'+~[b](e);~\"){n[k]~a+1,b):~m[t+1](~return~lnk~mobile~height~events~random~code~wd.~=un~un,~,pev~'MSIE ~rs,~Time~floor(~atch~s.num(~s"
+".ape(~s.pg~m._e~s.c_gd~,'lt~.inner~transa~;s.gl(~idt='+~',s.bc~page~Group,~.fromC~sByTag~?'&~+';'~&&o~1);~}}}}~){t=~[t]=~[n];~>=5)~[t](~,1)!='~!a[t])~~s._c=@Uc';`I=`z`5!`I`m$R`I`ml`N;`I`mn=0;}s@4l="
+"`I`ml;s@4n=`I`mn;s@4l[s@4@ys;`I`mn++;s.m`0m){`2@nm)`4'{$o0`9fl`0x,l){`2x?@nx)`30,l):x`9co`0o`F!o)`2o;`Ln`C,x;`vx$3o)@tx`4'select$o0&&x`4'filter$o0)n[x]=o[x];`2n`9num`0x){x`i+x;`v`Lp=0;p<x`A;p++)@t("
+"@c')`4x`3p,p$Z<0)`20;`21`9rep=s_r;s.spf`0t,a){a[a`A]=t;`20`9sp`0x,d`1,a`N`5$e)a=$e(d);`c`Mx,d,'sp@0a);`2a`9ape`0x`1,h=@cABCDEF',i,c=s.@L,n,l,e,y`i;c=c?c`E$W`5x){x`i+x`5c^SAUTO'^w'').c^vAt){`vi=0;i<"
+"x`A^X{c=x`3i,i+#Un=x.c^vAt(i)`5n>127){l=0;e`i;^Cn||l<4){e=h`3n%16,n%16+1)+e;n=(n-n%16)/16;l++}y+='%u'+e}`6c^S+')y+='%2B';`cy+=^pc)}x=y^bx=x?^1^p''+x),'+`H%2B'):x`5x&&c^5em==1&&x`4'%u$o0&&x`4'%U$o0)"
+"{i=x`4'%^Y^Ci>=0){i++`5h`38)`4x`3i,i+1)`E())>=0)`2x`30,i)+'u00'+x`3i);i=x`4'%',i)#V`2x`9epa`0x`1;`2x?un^p^1''+x,'+`H ')):x`9pt`0x,d,f,a`1,t=x,z=0,y,r;^Ct){y=t`4d);y=y<0?t`A:y;t=t`30,y);^Ft,$Xt,a)`5"
+"r)`2r;z+=y+d`A;t=x`3z,x`A);t=z<x`A?t:''}`2''`9isf`0t,a){`Lc=a`4':')`5c>=0)a=a`30,c)`5t`30,2)^S$l`32);`2(t!`i&&t==a)`9fsf`0t,a`1`5`Ma,`H,'is@0t))@W+=(@W!`i?`H`n+t;`20`9fs`0x,f`1;@W`i;`Mx,`H,'fs@0f);"
+"`2@W`9si`0wd`1,c`i+s_gi,a=c`4\"{\"),b=c`f\"}\"),m;c=s_fe(a>0&&b>0?c`3$u0)`5wd&&#3^9&&c){#3^T'fun^I s_sv(o,n,k){`Lv=o[k],i`5v`F`ystring\"||`ynumber\")n[k]=v;`cif (`yarray$t`N;`vi=0;i<v`A^X@6`cif (`y"
+"object$t`C;`vi$3v)@6}}fun^I $h{`Lwd=`z,s,i,j,c,a,b;wd^zgi`7\"un\",\"pg\",\"ss\",$rc+'\");#3^t$r@B+'\");s=#3s;s.sa($r^4+'\"`V^3=wd;`M^2,\",\",\"vo1\",t`G\\'\\'`5t.m_l&&@i)`vi=0;i<@i`A^X{n=@i[i]`5$Rm"
+"=t#Yc=t[@F]`5m&&c){c=\"\"+c`5c`4\"fun^I\")>=0){a=c`4\"{\");b=c`f\"}\");c=a>0&&b>0?c`3$u0;s[@F@g=c`5#F)s.@f(n)`5s[n])`vj=0;j<$A`A;j++)s_sv(m,s[n],$A[j])#V}`Le,o,t@9o=`z.opener`5o#T^zgi#Wo^zgi($r^4+'"
+"\")`5t)$h}`e}',1)}`9c_d`i;#Gf`0t,a`1`5!#Ct))`21;`20`9c_gd`0`1,d=`I`P^D@7,n=s.fpC`O,p`5!n)n=s.c`O`5d@S$B@qn?^Hn):2;n=n>2?n:2;p=d`f'.')`5p>=0){^Cp>=0&&n>1$Vd`f'.',p-#Un--}$B=p>0&&`Md,'.`Hc_gd@00)?d`3"
+"p):d}}`2$B`9c_r`0k`1;k=#Dk);`Lc=' '+s.d.^0,i=c`4' '+k+@p,e=i<0?i:c`4';',i),v=i<0?'':@hc`3i+2+k`A,e<0?c`A:e));`2v!='[[B]]'?v:''`9c_w`0k,v,e`1,d=#G(),l=s.^0@G,t;v`i+v;l=l?@nl)`E$W`5@5@a#W(v!`i?^Hl?l:"
+"0):-60)`5t){e`h;e.set#9(e`d+(t*1000))}`pk@a@1d.^0=k+'`Tv!`i?v:'[[B]]')+'; path=/;'+(@5?' expires='+e.toGMT^B()#S`n+(d?' domain='+d#S`n;`2^dk)==v}`20`9eh`0o,e,r,f`1,b='s^xe+'^xs@4n,n=-1,l,i,x`5!^fl)"
+"^fl`N;l=^fl;`vi=0;i<l`A&&n<0;i++`Fl[i].o==o&&l[i].e==e)n=i`pn<0@qi;l[n]`C}x=l#Yx.o=o;x.e=e;f=r?x.b:f`5r||f){x.b=r?0:o[e];x.o[e]=f`px.b){x.o[b]=x.b;`2b}`20`9cet`0f,a,t,o,b`1,r,^m`5`S>=5^w!s.^n||`S>="
+"7)){^m`7's`Hf`Ha`Ht`H`Le,r@9^F$Xa)`er=s.m(t)?s#ae):t(e)}`2r^Yr=^m(s,f,a,t)^b@ts.^o^5u`4#74@o0)r=s.m(b)?s[b](a):b(a);else{^f(`I,'@M',0,o);^F$Xa`Veh(`I,'@M',1)}}`2r`9g^3et`0e`1;`2s.^3`9g^3oe`7'e`H`Ls"
+"=`B,c;^f(`z,\"@M\",1`Ve^3=1;c=s.t()`5c)s.d.write(c`Ve^3=0;`2@z'`Vg^3fb`0a){`2`z`9g^3f`0w`1,p=w^8,l=w`P;s.^3=w`5p&&p`P!=l&&p`P^D==l^D@1^3=p;`2s.g^3f(s.^3)}`2s.^3`9g^3`0`1`5!s.^3@1^3=`I`5!s.e^3)s.^3="
+"s.cet('g^3@0s.^3,'g^3et',s.g^3oe,'g^3fb')}`2s.^3`9mrq`0u`1,l=@C],n,r;@C]=0`5l)`vn=0;n<l`A;n++){r=l#Ys.mr(0,0,r.r,0,r.t,r.u)}`9br`0id,rs`1`5s.@P`U$p^e@Ubr',rs))$C=rs`9flush`U`0`1;s.fbr(0)`9fbr`0id`1"
+",br=^d@Ubr')`5!br)br=$C`5br`F!s.@P`U)^e@Ubr`H'`Vmr(0,0,br)}$C=0`9mr`0$0,q,#8id,ta,u`1,dc=s.dc,t1=s.`Q,t2=s.`Q^j,tb=s.`QBase,p='.sc',ns=s.`a`qspace,un=u?u:(ns?ns:s.fun),unc=^1#5'_`H-'),r`C,l,imn=@Ui"
+"^x(un),im,b,e`5!rs`Ft1`Ft2^5ssl)t1=t2^b@t!ns)ns#4c`5!tb)tb='$O`5dc)dc=@ndc)`8;`cdc='d1'`5tb^S$O`Fdc^Sd1$i12';`6dc^Sd2$i22';p`i}t1=ns+'.'+dc+'.'+p+tb}rs=$4'+(@A?'s'`n+'://'+t1+'/b/ss/'+^4+'/'+(s.$y?"
+"'5.1':'1'$TH.19.3/'+$0+'?AQB=1&ndh=1'+(q?q`n+'&AQE=1'`5^g@Ss.^o`F`S>5.5)rs=^s#84095);`crs=^s#82047)`pid@1br(id,rs);$w}`ps.d.images&&`S>=3^w!s.^n||`S>=7)^w@Y<0||`S>=6.1)`F!s.rc)s.rc`C`5!^V){^V=1`5!s"
+".rl)s.rl`C;@Cn]`N;^T'@t`z`ml)`z.`B@J)',750)^bl=@Cn]`5l){r.t=ta;r.u#4;r.r=rs;l[l`A]=r;`2''}imn+='^x^V;^V++}im=`I[imn]`5!im)im=`I[im@ynew Image;im^zl=0;im.o^L`7'e`H^Z^zl=1;`Lwd=`z,s`5wd`ml){s=#3`B;s@"
+"J`Vnrs--`5!$D)`Ym(\"rr\")}')`5!$D@1nrs=1;`Ym('rs')}`c$D++;im@O=rs`5rs`4$9=@o0^w!ta||ta^S_self$qta^S_top$q(`I.@7&&ta==`I.@7))){b=e`h;^C!im^zl&&e`d-b`d<500)e`h}`2''}`2'<im'+'g sr'+'c=$rrs+'\" width=1"
+" $z=1 border=0 alt=\"\">'`9gg`0v`1`5!`I['s^xv])`I['s^xv]`i;`2`I['s^xv]`9glf`0t,a`Ft`30,2)^S$l`32);`Ls=^Z,v=s.gg(t)`5v)s#Xv`9gl`0v`1`5#E)`Mv,`H,'gl@00)`9gv`0v`1;`2s['vpm^xv]?s['vpv^xv]:(s[v]?s[v]`n`"
+"9havf`0t,a`1,b=t`30,4),x=t`34),n=^Hx),k='g^xt,m='vpm^xt,q=t,v=s.`X@bVa#8e=s.`X@b^Ws,mn;@d$Et)`5s[k]`F$8||@X||^O`F$8){mn=$8`30,1)`E()+$8`31)`5$F){v=$F.^KVars;e=$F.^K^Ws}}v=v?v+`H+^h+`H+^h2:''`5v@S`M"
+"v,`H,'is@0t))s[k]`i`5`J#0'&&e)@ds.fs(s[k],e)}s[m]=0`5`J^R`KD';`6`J`aID`Kvid';`6`J^N^Qg'`j`6`J`b^Qr'`j`6`Jvmk$q`J`a@R`Kvmt';`6`J`D^Qvmf'`5@A^5`D^j)s[k]`i}`6`J`D^j^Qvmf'`5!@A^5`D)s[k]`i}`6`J@L^Qce'`5"
+"s[k]`E()^SAUTO')@d'ISO8859-1';`6s.em==2)@d'UTF-8'}`6`J`a`qspace`Kns';`6`Jc`O`Kcdp';`6`J^0@G`Kcl';`6`J^y`Kvvp';`6`J@N`Kcc';`6`J$c`Kch';`6`J#J^IID`Kxact';`6`J$1`Kv0';`6`J^a`Ks';`6`J^A`Kc';`6`J`s^u`Kj"
+"';`6`J`k`Kv';`6`J^0@I`Kk';`6`J^7@D`Kbw';`6`J^7^k`Kbh';`6`J`l`Kct';`6`J@8`Khp';`6`Jp^P`Kp';`6#Cx)`Fb^Sprop`Kc$Y`6b^SeVar`Kv$Y`6b^Slist`Kl$Y`6b^Shier^Qh'+n`j`ps[k]@s`X`q'@s`X^c')$G+='&'+q+'`Ts[k]);}`"
+"2''`9hav`0`1;$G`i;`M^i,`H,'hav@00);`2$G`9lnf`0^l`8@3`8:'';`Lte=t`4@p`5$Ste>0&&h`4t`3te$Z>=0)`2t`30,te);`2''`9ln`0h`1,n=s.`X`qs`5n)`2`Mn,`H,'ln@0h);`2''`9ltdf`0^l`8@3`8:'';`Lqi=h`4'?^Yh=qi>=0?h`30,q"
+"i):h`5$Sh`3h`A-(t`A$Z^S.'+t)`21;`20`9ltef`0^l`8@3`8:''`5$Sh`4t)>=0)`21;`20`9lt`0h`1,lft=s.`XDow^LFile^cs,lef=s.`XEx`r,$2=s.`XIn`r;$2=$2?$2:`I`P^D@7;h=h`8`5s.^KDow^LLinks&&lf$S`Mlft,`H#Hd@0h))`2'd'`"
+"5s.^K@K&&h`30#b# '^wlef||$2)^w!lef||`Mlef,`H#He@0h))^w!$2$p`M$2,`H#He@0h)))`2'e';`2''`9lc`7'e`H`Ls=`B,b=^f(^Z,\"`o\"`V$x=$6^Z`Vt(`V$x=0`5b)`2^Z$s`2@z'`Vbc`7'e`H`Ls=`B,f,^m`5s.d^5d.all^5d.all.cppXYc"
+"tnr)$w;^O=e@O`Z?e@O`Z:e$d;^m`7\"s\",\"`Le@9@t^O^w^O.tag`q||^O^8`Z||^O^8Node))s.t()`e}\");^m(s`Veo=0'`Voh`0o`1,l=`I`P,h=o^q?o^q:'',i,j,k,p;i=h`4':^Yj=h`4'?^Yk=h`4'/')`5h^wi<0||(j>=0&&i>j)||(k>=0&&i>"
+"k))$Vo`g#T`g`A>1?o`g:(l`g?l`g`n;i=l.path@7`f'/^Yh=(p?p+'//'`n+(o^D?o^D:(l^D?l^D`n)+(h`30#b/'?l.path@7`30,i<0?0:i$T'`n+h}`2h`9ot`0o){`Lt=o.tag`q;t=$St`E?t`E$W`5`JSHAPE')t`i`5t`F`JINPUT'&&@E&&@E`E)t="
+"@E`E();`6!$So^q)t='A';}`2t`9oid`0o`1,^J,p,c,n`i,x=0`5t@S^6$Vo`g;c=o.`o`5o^q^w`JA$q`JAREA')^w!c$pp||p`8`4'`s$o0))n@w`6c@q^1s.rep(^1s.rep@nc,\"\\r@r\"\\n@r\"\\t@r' `H^Yx=2}`6$f^w`JINPUT$q`JSUBMIT')@q"
+"$f;x=3}`6o@O&&`JIMAGE')n=o@O`5$R^6=^sn$5;^6t=x}}`2^6`9rqf`0t,un`1,e=t`4@p,u=e>=0?`H+t`30,e)+`H:'';`2u&&u`4`H+un+`H)>=0?@ht`3e$Z:''`9rq`0un`1,c#4`4`H),v=^d@Usq'),q`i`5c<0)`2`Mv,'&`Hrq@0un);`2`M#5`H,"
+"'rq',0)`9sqp`0t,a`1,e=t`4@p,q=e<0?'':@ht`3e+1)`Vsqq[q]`i`5e>=0)`Mt`30,e),`H@l`20`9sqs`0#5q`1;^Gu[u@yq;`20`9sq`0q`1,k=@Usq',v=^dk),x,c=0;^Gq`C;^Gu`C;^Gq[q]`i;`Mv,'&`Hsqp',0);`M^4,`H@lv`i;`vx$3^Gu`W)"
+"^Gq[^Gu[x]]+=(^Gq[^Gu[x]]?`H`n+x;`vx$3^Gq`W^5sqq[x]^wx==q||c<2)){v+=(v#R'`n+^Gq[x]+'`Tx);c++}`2^ek,v,0)`9wdl`7'e`H`Ls=`B,r=@z,b=^f(`I,\"o^L\"),i,o,oc`5b)r=^Z$s`vi=0;i<s.d.`Xs`A^X{o=s.d.`Xs[i];oc=o."
+"`o?\"\"+o.`o:\"\"`5(oc`4$L<0||oc`4\"^zoc(\")>=0)#Tc`4$j<0)^f(o,\"`o\",0,s.lc);}`2r^Y`Is`0`1`5`S>3^w!^g$ps.^o||`S#Z`Fs.b^5$N^W)s.$N^W('`o#M);`6s.b^5b.add^W$K)s.b.add^W$K('click#M,false);`c^f(`I,'o^L"
+"',0,`Il)}`9vs`0x`1,v=s.`a^U,g=s.`a^U#Ok=@Uvsn^x^4+(g?'^xg`n,n=^dk),e`h,y=e.g@Q);e.s@Qy+10@x1900:0))`5v){v*=100`5!n`F!^ek,x,e))`20;n=x`pn%10000>v)`20}`21`9dyasmf`0t,m`F$Sm&&m`4t)>=0)`21;`20`9dyasf`0"
+"t,m`1,i=t?t`4@p:-1,n,x`5i>=0&&m){`Ln=t`30,i),x=t`3i+1)`5`Mx,`H,'dyasm@0m))`2n}`20`9uns`0`1,x=s.`RSele^I,l=s.`RList,m=s.`RM#B,n,i;^4=^4`8`5x&&l`F!m)m=`I`P^D`5!m.toLowerCase)m`i+m;l=l`8;m=m`8;n=`Ml,'"
+";`Hdyas@0m)`5n)^4=n}i=^4`4`H`Vfun=i<0?^4:^4`30,i)`9sa`0un`1;^4#4`5!@B)@B#4;`6(`H+@B+`H)`4un)<0)@B+=`H+un;^4s()`9m_i`0n,a`1,m,f=n`30,1),r,l,i`5!`Yl)`Yl`C`5!`Ynl)`Ynl`N;m=`Yl[n]`5!a&&m&&#F@Sm@4)`Ya(n"
+")`5!m){m`C,m._c=@Um';m@4n=`I`mn;m@4l=s@4l;m@4l[m@4@ym;`I`mn++;m.s=s;m._n=n;$A`N('_c`H_in`H_il`H_i`H_e`H_d`H_dl`Hs`Hn`H_r`H_g`H_g1`H_t`H_t1`H_x`H_x1`H_rs`H_rr`H_l'`Vm_l[@ym;`Ynl[`Ynl`A]=n}`6m._r@Sm."
+"_m){r=m._r;r._m=m;l=$A;`vi=0;i<l`A^X@tm[l[i]])r[l[i]]=m[l[i]];r@4l[r@4@yr;m=`Yl[@yr`pf==f`E())s[@ym;`2m`9m_a`7'n`Hg`H@t!g)g=@F;`Ls=`B,c=s[g@g,m,x,f=0`5!c)c=`I$g@g`5c&&s_d)s[g]`7\"s\",s_ft(s_d(c)));"
+"x=s[g]`5!x)x=s[g]=`I$g];m=`Yi(n,1)`5x){m@4=f=1`5(\"\"+x)`4\"fun^I\")>=0)x(s);`c`Ym(\"x\",n,x)}m=`Yi(n,1)`5@jl)@jl=@j=0;`tt();`2f'`Vm_m`0t,n,d#W'^xt;`Ls=^Z,i,x,m,f='^xt`5`Yl&&`Ynl)`vi=0;i<`Ynl`A^X{x"
+"=`Ynl[i]`5!n||x==$Rm=`Yi(x)`5m[t]`F`J_d')`21`5d)m#ad);`cm#a)`pm[t+1]@Sm[f]`Fd)$vd);`c$v)}m[f]=1}}`20`9@f`0n,u,d,l`1,m,i=n`4':'),g=i<0?@F:n`3i+1),o=0,f,c=s.h?s.h:s.b,^m`5i>=0)n=n`30,i);m=`Yi(n)`5(l$"
+"p`Ya(n,g))&&u^5d&&c^5$P`Z`Fd){@j=1;@jl=1`p@A)u=^1u,$4:`Hhttps:^Yf`7'e`H`B.m_a(\"@e\",$rg+'\")^Y^m`7's`Hf`Hu`Hc`H`Le,o=0@9o=s.$P`Z(\"script\")`5o){@E=\"text/`s\"`5f)o.o^L=f;o@O=u;c.appendChild(o)}`e"
+"o=0}`2o^Yo=^m(s,f,u,c)}`cm=`Yi(n);#F=1;`2m`9vo1`0t,a`Fa[t]||$a)^Z#Xa[t]`9vo2`0t,a`F#c{a#X^Z[t]`5#c$a=1}`9dlt`7'`Ls=`B,d`h,i,vo,f=0`5`tl)`vi=0;i<`tl`A^X{vo=`tl[i]`5vo`F!`Ym(\"d\")||d`d-$M>=^E){`tl[i"
+"]=0;s.t(@u}`cf=1}`p`ti)clear#9out(`ti`Vdli=0`5f`F!`ti)`ti=^T`tt,^E)}`c`tl=0'`Vdl`0vo`1,d`h`5!@uvo`C;`M^2,`H$H2',@u;$M=d`d`5!`tl)`tl`N;`tl[`tl`A]=vo`5!^E)^E=250;`tt()`9t`0vo,id`1,trk=1,tm`h,sed=Math"
+"&&@V#1?@V#A@V#1()*10000000000000):tm`d,$0='s'+@V#Atm`d/10800000)%10+sed,y=tm.g@Q),vt=tm.getDate($T`xMonth($T'@xy+1900:y)+' `xHour$U:`xMinute$U:`xSecond$U `xDay()+' `x#9zoneO$7(),^m,^3=s.g^3(),ta`i,"
+"q`i,qs`i,#2`i,vb`C#K^2`Vuns()`5!s.td){`Ltl=^3`P,a,o,i,x`i,c`i,v`i,p`i,bw`i,bh`i,^M0',k=^e@Ucc`H@z',0@2,hp`i,ct`i,pn=0,ps`5^B&&^B.prototype){^M1'`5j.m#B){^M2'`5tm.setUTCDate){^M3'`5^g^5^o&&`S#Z^M4'`"
+"5pn.toPrecisio$R^M5';a`N`5a.forEach){^M6';i=0;o`C;^m`7'o`H`Le,i=0@9i=new Iterator(o)`e}`2i^Yi=^m(o)`5i&&i.next)^M7'#V`p`S>=4)x=^rwidth+'x'+^r$z`5s.isns||s.^n`F`S>=3$b`k(@2`5`S>=4){c=^rpixelDepth;bw"
+"=`I#I@D;bh=`I#I^k}}$I=s.n.p^P}`6^g`F`S>=4$b`k(@2;c=^r^A`5`S#Z{bw=s.d.^9`Z.o$7@D;bh=s.d.^9`Z.o$7^k`5!s.^o^5b){^m`7's`Htl`H`Le,hp=0`uh$m\");hp=s.b.isH$m(tl)?\"Y\":\"N\"`e}`2hp^Yhp=^m(s,tl);^m`7's`H`L"
+"e,ct=0`uclientCaps\");ct=s.b.`l`e}`2ct^Yct=^m(s)}}}`cr`i`p$I)^Cpn<$I`A&&pn<30){ps=^s$I[pn].@7$5#S`5p`4ps)<0)p+=ps;pn++}s.^a=x;s.^A=c;s.`s^u=j;s.`k=v;s.^0@I=k;s.^7@D=bw;s.^7^k=bh;s.`l=ct;s.@8=hp;s.p"
+"^P=p;s.td=1`p@u{`M^2,`H$H2',vb);`M^2,`H$H1',@u`ps.useP^P)s.doP^P(s);`Ll=`I`P,r=^3.^9.`b`5!s.^N)s.^N=l^q?l^q:l`5!s.`b@Ss._1_`b@1`b=r;s._1_`b=1}`Ym('g')`5(vo&&$M)$p`Ym('d')`F@X||^O){`Lo=^O?^O:@X`5!o)"
+"`2'';`Lp=$E'#N`q'),w=1,^J,@k,x=^6t,h,l,i,oc`5^O#T==^O){^Co@Sn@sBODY'){o=o^8`Z?o^8`Z:o^8Node`5!o)`2'';^J;@k;x=^6t}oc=o.`o?''+o.`o:''`5(oc`4$L>=0#Tc`4\"^zoc(\")<0)||oc`4$j>=0)`2''}ta=n?o$d:1;h@wi=h`4"
+"'?^Yh=s.`X@m^B||i<0?h:h`30,i);l=s.`X`q?s.`X`q:s.ln(h);t=s.`X^c?s.`X^c`8:s.lt(h)`5t^wh||l))q+=$9=$x^x(`Jd$q`Je'?#Dt):'o')+(h?$9v1`Th)`n+(l?$9v2`Tl)`n;`ctrk=0`5s.^K@Z`F!p$V$E'^N^Yw=0}^J;i=o.sourceInd"
+"ex`5@H')@q@H^Yx=1;i=1`pp&&n&&t)qs='&pid`T^sp,255))+(w#Rp#Lw`n+'&oid`T^sn$5)+(x#Ro#Lx`n+'&ot`Tt)+(i#Roi='+i`n}`p!trk@Sqs)`2'';@v=s.vs(sed)`5trk`F@v)#2=s.mr($0,(vt#Rt`Tvt)`n+s.hav()+q+(qs?qs:s.rq(^4)"
+"),0,id,ta);qs`i;`Ym('t')`5s.p_r)s.p_r(`V`b`i}^G(qs);^b`t(@u;`p@u`M^2,`H$H1',vb`G''`5#E)`I^z$x=`I^zeo=`I^z`X`q=`I^z`X^c`i`5!id@Ss.tc@1tc=1;s.flush`U()}`2#2`9tl`0o,t,n,vo`1;@X=$6o`V`X^c=t;s.`X`q=n;s."
+"t(@u}`5pg){`I^zco`0o){`L^t\"_\",1,#U`2$6o)`9wd^zgs`0u$R`L^t#51,#U`2s.t()`9wd^zdc`0u$R`L^t#5#U`2s.t()}}@A=(`I`P`g`8`4$4s@o0`Vd=^9;s.b=s.d.body`5$n`Z#Q`q@1h=$n`Z#Q`q('HEAD')`5s.h)s.h=s.h[0]}s.n=navig"
+"ator;s.u=s.n.userAgent;@Y=s.u`4'N$k6/^Y`Lapn$Q`q,v$Q^u,ie=v`4#7'),o=s.u`4'@T '),i`5v`4'@T@o0||o>0)apn='@T';^g$J^SMicrosoft Internet Explorer'`Visns$J^SN$k'`V^n$J^S@T'`V^o=(s.u`4'Mac@o0)`5o>0)`S`ws."
+"u`3o+6));`6ie>0){`S=^Hi=v`3ie+5))`5`S>3)`S`wi)}`6@Y>0)`S`ws.u`3@Y+10));`c`S`wv`Vem=0`5^B#P^v){i=^p^B#P^v(256))`E(`Vem=(i^S%C4%80'?2:(i^S%U0100'?1:0))}s.sa(un`Vvl_l='^R,`aID,vmk,`a@R,`D,`D^j,ppu,@L,"
+"`a`qspace,c`O,^0@G,#N`q,^N,`b,@N';^i=^h+',^y,$c,server,#N^c,#J^IID,purchaseID,$1,state,zip,#0,products,`X`q,`X^c';`v`Ln=1;n<51;n++)^i+=',prop@e,eVar@e,hier@e,list$Y^h2=',tnt,pe#61#62#63,^a,^A,`s^u,"
+"`k,^0@I,^7@D,^7^k,`l,@8,p^P';^i+=^h2;^2=^i+',`Q,`Q^j,`QBase,fpC`O,@P`U,$y,`a^U,`a^U#O`RSele^I,`RList,`RM#B,^KDow^LLinks,^K@K,^K@Z,`X@m^B,`XDow^LFile^cs,`XEx`r,`XIn`r,`X@bVa#8`X@b^Ws,`X`qs,$x,eo,_1_"
+"`b';#E=pg#K^2)`5!ss)`Is()",
w=window,l=w.s_c_il,n=navigator,u=n.userAgent,v=n.appVersion,e=v.indexOf('MSIE '),m=u.indexOf('Netscape6/'),a,i,s;if(un){un=un.toLowerCase();if(l)for(i=0;i<l.length;i++){s=l[i];if(s._c=='s_c'){if(s.oun==un)return s;else if(s.fs&&s.sa&&s.fs(s.oun,un)){s.sa(un);return s}}}}
w.s_r=new Function("x","o","n","var i=x.indexOf(o);if(i>=0&&x.split)x=(x.split(o)).join(n);else while(i>=0){x=x.substring(0,i)+n+x.substring(i+o.length);i=x.indexOf(o)}return x");
w.s_d=new Function("x","var t='`^@$#',l='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',d,n=0,b,k,w,i=x.lastIndexOf('~~');if(i>0){d=x.substring(0,i);x=x.substring(i+2);while(d){w=d;i"
+"=d.indexOf('~');if(i>0){w=d.substring(0,i);d=d.substring(i+1)}else d='';b=(n-n%62)/62;k=n-b*62;k=t.substring(b,b+1)+l.substring(k,k+1);x=s_r(x,k,w);n++}for(i=0;i<5;i++){w=t.substring(i,i+1);x=s_r(x"
+",w+' ',w)}}return x");
w.s_fe=new Function("c","return s_r(s_r(s_r(c,'\\\\','\\\\\\\\'),'\"','\\\\\"'),\"\\n\",\"\\\\n\")");
w.s_fa=new Function("f","var s=f.indexOf('(')+1,e=f.indexOf(')'),a='',c;while(s>=0&&s<e){c=f.substring(s,s+1);if(c==',')a+='\",\"';else if((\"\\n\\r\\t \").indexOf(c)<0)a+=c;s++}return a?'\"'+a+'\"':"
+"a");
w.s_ft=new Function("c","c+='';var s,e,o,a,d,q,f,h,x;s=c.indexOf('=function(');while(s>=0){s++;d=1;q='';x=0;f=c.substring(s);a=s_fa(f);e=o=c.indexOf('{',s);e++;while(d>0){h=c.substring(e,e+1);if(q){i"
+"f(h==q&&!x)q='';if(h=='\\\\')x=x?0:1;else x=0}else{if(h=='\"'||h==\"'\")q=h;if(h=='{')d++;if(h=='}')d--}if(d>0)e++}c=c.substring(0,s)+'new Function('+(a?a+',':'')+'\"'+s_fe(c.substring(o+1,e))+'\")"
+"'+c.substring(e+1);s=c.indexOf('=function(')}return c;");
c=s_d(c);if(e>0){a=parseInt(i=v.substring(e+5));if(a>3)a=parseFloat(i)}else if(m>0)a=parseFloat(u.substring(m+10));else a=parseFloat(v);if(a>=5&&v.indexOf('Opera')<0&&u.indexOf('Opera')<0){w.s_c=new Function("un","pg","ss","var s=this;"+c);return new s_c(un,pg,ss)}else s=new Function("un","pg","ss","var s=new Object;"+s_ft(c)+";return s");return s(un,pg,ss)}




if(typeof ncbi == "undefined"){
    ncbi = {}; 
}

ncbi.sg = function() {};
ncbi.sg.getInstance = function() { 
    if(!ncbi.sg._instance){
        ncbi.sg._instance = new ncbi.sg();
    }
    return ncbi.sg._instance;
};
ncbi.sg._instance = null;
ncbi.sg.omnDictMap = {
    "pagename": ["pageName"],
    "ncbi_app": ["channel"],
    "server": ["server"],
    "ncbi_pagetype": ["pageType"],
    "ncbi_phid": ["prop1"],
    "ncbi_db": ["prop2", "prop4"],
    "ncbi_term": ["prop3"],
    "ncbi_type": ["prop4"],
    "ncbi_report": ["prop5"],
    "ncbi_pagesize": ["prop6"],
    "ncbi_sortorder": ["prop7"],
    "ncbi_pageno": ["prop8"],
    "formtype": ["prop9"],
    "ncbi_resultcount": ["prop10"],
    "ncbi_linkname": ["prop11"],
    "ncbi_dbfrom": ["prop12"],
    "linkid": ["prop13"],
    "linkname": ["prop14"],
    "linksid": ["prop15"],
    "ncbi_op": ["prop16"],
    "ncbi_limits": ["prop17"],
    //"ncbi_advlimits": ["prop18"],
    "ncbi_limitvalues": ["prop19"],
    //"ncbi_advlimitsvalues" : ["prop20"],
    "ncbi_pdid": ["prop21"],
    "ncbi_sessionid": ["prop22"],
    "sitesect2": ["prop23"],
    "subsect3": ["prop24"],
    "subsect4": ["prop25"],
    "ncbi_pcid": ["prop26"],
    "jserror": ["prop27"],
    "jserrortype": ["prop28"],
    "ncbi_servererror": ["prop29"],
    "ncbi_servererrortype": ["prop30"],
    "jsloadtime": ["prop31"],
    "jsevent": ["prop37"],
    "ncbi_filter": ["prop38"],
    "adid": ["prop39"],
    "adtargetid": ["prop40"],
    "heir1": ["heir1"]
}

ncbi.sg.prototype = {

    //Needs to be called manually
    init : function(){
        this.isProcessRunning = true;
        this._setUpOmnValues();
        this._setUpPathParts();
        this._setUpCustomProps();        
        this.send( "init" );        
    },
    
    //holds temp lookup dict 
    _vals : {},
    _hasInitRun : false,

    //used for temp holding place do build app path
    _pathParts: {
        "part1": "",
        "part2": "",
        "part3": "",
        "part4": ""
    },
    
    //gathers meta data
    _setUpOmnValues: function() {
        var mTags = document.getElementsByTagName("meta");
        for (var i = 0; i < mTags.length; i++) {
            var mName = mTags[i].name;
            if (mName.indexOf("ncbi_") === 0) {
                var mContent = mTags[i].content;
                this.addEntry(mName, mContent);
            }
        }
    },
    
    //gathers up specific meta data
    _setUpSubsetOmnValues: function(subsetData) {
        var mTags = document.getElementsByTagName("meta");        
        for (var i = 0; i < mTags.length; i++) {            
            var mName = mTags[i].name;
            if(mName){
                if (mName.indexOf("ncbi_") === 0 && subsetData.indexOf(mName) !== -1 ) {
                    var mContent = mTags[i].content;
                    this.addEntry(mName, mContent);
                }
            }
        }
    },
    
    //inserts entry into temp dict
    addEntry: function(mName, mContent) {
        if(mContent===undefined || mContent.length===0) return;
        var dictEntry = ncbi.sg.omnDictMap[mName];
        if (dictEntry) {
            this._vals[mName] = {
                sProp : dictEntry,
                value : mContent
            };            
        } 
        else if (console && console.warn) {
            console.warn("Unkown NCBI to Omn mapping: \ntag: " + mName + "\nvalue: " + mContent);
        }
    },
    
    //cleans up temp dict
    removeAllEntries : function(){
        this._vals = {};
        for(var p in this._pathParts){
            this._pathParts[p] = "";
        }        
    },
    
    //builds up Omn path settings
    _setUpCustomProps: function() {
        var a = this._pathParts.part1;
        var b = (this._pathParts.part2.length > 0) ? ":" + this._pathParts.part2: "";
        var c = (this._pathParts.part3.length > 0) ? ":" + this._pathParts.part3: "";
        var d = (this._pathParts.part4.length > 0) ? ":" + this._pathParts.part4: "";
        var custData = {
            "pagename": a + b + c,
            "server": window.location.hostname,
            "sitesect2": a + b,
            "subsect3": a + b + c,
            "subsect4": a + b + c + d,
            "heir1": (a + b + c + d).replace(/:/g, "|")
        }
        for (var prop in custData) {
            this.addEntry(prop, custData[prop]);
        }
    },
    
    //sets up building blocks for the path
    _setUpPathParts: function() {
    
        var ncbi_app = this._vals["ncbi_app"];
        var ncbi_db = this._vals["ncbi_db"];
        var ncbi_pdid = this._vals["ncbi_pdid"];
        var ncbi_pcid = this._vals["ncbi_pcid"];
       
        this._pathParts.part1 = (ncbi_app !== undefined)?ncbi_app.value:"";
        this._pathParts.part2 = (ncbi_db !== undefined)?ncbi_db.value:"";
        this._pathParts.part3 = (ncbi_pdid !== undefined)?ncbi_pdid.value:"";
        this._pathParts.part4 = (ncbi_pcid !== undefined)?ncbi_pcid.value:"";
        
    },   
    
    //Call Omn/AL
    send : function( method, callbackFnc ){
    
        var al = [];
        
        for(var prop in this._vals){
            var data = this._vals[prop];
            var val = this._vals[prop].value;           
            var sProp = this._vals[prop].sProp;            
            for(var i=0;i<sProp.length;i++){
                s[sProp[i]] = val;
            }
            al.push(prop + "=" + encodeURIComponent(val) );                                  
        }
        
        var appStr = al.join("&");
        if(console && console.info) console.info("sg Data:\n\n" + al.join("\n"));
        
        if(s_account!=="none"){

            this.sendOmn( method );
           //this.sendAl( method, appStr, callbackFnc );

            this._hasInitRun = true;

            var ref=this;        
            setTimeout(function(){ ref.isProcessRunning = false; ref.runSGProcess();}, 300);
            
        }        
        
    },
    
    //send to Omn
    sendOmn : function( method ){
        
        if(console && console.info) console.info("Setting Omn");
        
        if(method === "init"){ //setup
            var s_code = s.t();
            if(s_code){
                document.write(s_code);
            }
        }
        else if(this._areEventsSG()){ //click, load, error events
           s.tl(); 
        }
        
    }, 
    
   /*ajax call to al
    sendAl : function( method, data, callbackFnc ){        
        if( method === "init" || this._areEventsSG() ){    
            if(console && console.info) console.info("al Sent: \n" +  data );
            this.makeAjaxCall("corecgi/s.cgi?" + data, function() { if(console && console.info){ console.info ("al: done");} if(typeof callbackFnc === "function")callbackFnc(); } );     
            
        }
    },*/
  
  
    //Queue in case multiple things need to be noted at one time
    _processingQueue: [],
    isProcessRunning : false,
    addSGProcess: function(data){
        this._processingQueue.push(data);
    },
    getSGProcess: function(data){
        return this._processingQueue.shift(data);
    },
    
    //Process to execute data in the queue
    runSGProcess: function(){
        
        if(this.isProcessRunning || this._processingQueue.length===0 || !this._hasInitRun){
            return false;
        }

        this.isProcessRunning = true;        
        this.removeAllEntries();
        
        var nextSet = this.getSGProcess();
        s = s_gi(s_account);
        
        s.linkTrackVars='prop13,prop14,prop15';
        s.linkTrackEvents='None'; 
        
        this._setUpSubsetOmnValues(nextSet.metadata);
        
        if(console && console.info) console.info("Now sg " + nextSet.eventName + " to the server");       
        this.addEntry("jsevent", nextSet.eventName);
        
        for(var entry in nextSet.props){            
            this.addEntry(entry, nextSet.props[entry]);
        }
        
        this.send( nextSet.eventName, nextSet.callbackFnc );
        
        var ref=this;        
        setTimeout(function(){ ref.isProcessRunning = false; ref.runSGProcess();}, 300);
        
    },
    
    //JS Events
    noteEventData : function( jsEventName, custprops, metaData, callbackFnc){
        
        if(console && console.info) console.info("Adding " + jsEventName + " to the queue");
        this.addSGProcess( { "eventName" : jsEventName, "props" : custprops, "metadata": metaData, "callback" : callbackFnc } );
        this.runSGProcess();                 
        
    },
        
    //Need to hook up featured links with this!
    noteFeaturedClickEvent : function( link, onclickFnc ){
    
        function getQSValues( name ){
            var strFL = unescape(link.href)        
            var regEx = new RegExp("[?&]" + name + "=.*$","g");
            var strMatch = strFL.match(regEx);
            if(strMatch == null)return null
            var arrParts = strMatch.toString().split("&");
            return (arrParts[0].length==0)?arrParts[1].split("=")[1]:arrParts[0].split("=")[1];
        }
            
    
        var linkTxt = (link.textContent !== undefined)?link.textContent:link.innerText;
        var linkTar = encodeURIComponent(link.href);
        
        var linkData = {};
        linkData.adid = link.sid || link.id || linkTxt;
        if(linkTar)linkData.adtargetid = linkTar;
                 
        if(console && console.info) console.info("sg featured click: " + linkData.adid + "\t" + linkData.adtargetid );        
               
        var cbFnc = function(){};
        if(onclickFnc){
            cbFnc = function(){
                if(link.timer){ //should be cancelled later?
                    window.clearTimeout(link.timer);
                }
                onclickFnc();                
            }
        }
        
        this.noteEventData( "adclick", linkData, ["ncbi_sessionid"], cbFnc );
    
    },
    
    //button and link clicks
    noteLinkClickEventData : function( link, onclickFnc ){ 
                
        var linkTxt = (link.textContent !== undefined)?link.textContent:link.innerText;
        
        var linkData = {};
        linkData.linkid = link.id || "[" + linkTxt + "]";
        
        if(link.name) linkData.linkname = link.name;
        if(link.sid)linkData.linksid = link.sid;
                        
        if(console && console.info) console.info("sg click: " + linkData.linkid + "\t" + linkData.linkname + "\t" + linkData.linksid );
        
        
        var cbFnc = function(){};
        if(onclickFnc){
            cbFnc = function(){
                if(link.timer){
                    window.clearTimeout(link.timer);
                }
                onclickFnc();                
            }
        }
        
        this.noteEventData( "click", linkData, ["ncbi_sessionid"], cbFnc );
        
    },

    //Determine if user is in the percentage
    _isSG : null,
    _areEventsSG : function(){

        if(this._isSG===null){

            var mContent = null;

            var mTags = document.getElementsByTagName("meta");            
            for (var i = 0; i < mTags.length; i++) {
                var mName = mTags[i].name;
                if (mName === "ncbi_stat") {
                     mContent = mTags[i].content;                    
                     break;
                }
            }

            if(mContent === "true" || this.getCookie("NCBISTATON") === "true"){
                this._isSG = true; 
            }
            else if(mContent === "false"){
                this._isSG = false;
            }
            else if(!isNaN(mContent)){
                
                //check for cookie
                var statCookie = this.getCookie("NCBISTATG");
                if(statCookie.length > 0){
                    this._isSG = (statCookie==="true")?true:false;
                }
                else{                 
                    var n = parseFloat(mContent);
                    var rn = Math.floor(Math.random() * 100);
                    this._isSG = (rn <= n);
                    this.setCookie("NCBISTATG",this._isSG);   
                }

            }
            else{
                this._isSG = false;
            }            

        }
        return this._isSG;

    },


    setCookie : function(c_name,value,expiredays){
        var exdate=new Date();
        if(expiredays!=null){
            exdate.setDate(exdate.getDate()+expiredays);
        }
        document.cookie=c_name+ "=" +escape(value)+ ((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
    },

    getCookie : function(c_name){
        if (document.cookie.length>0){
            var c_start=document.cookie.indexOf(c_name + "=");
            if(c_start!=-1){ 
                c_start=c_start + c_name.length+1; 
                var c_end=document.cookie.indexOf(";",c_start);
                if (c_end==-1) c_end=document.cookie.length;
                return unescape(document.cookie.substring(c_start,c_end));
            } 
        }
        return "";
    }    
    
    //Start of Bare Bones Ajax Calls
    /*
    getTransport : function() {

        var req = null;

        //Look for the native object [IE7/IE8 supports it, but it is not 100% with all features]
        if (window.XMLHttpRequest) {
            try {
                req = new XMLHttpRequest();
                this.getTransport = function() {
                    return new XMLHttpRequest();
                };
            }
            catch(e0) {
                req = null;
            }
        }

        if (window.ActiveXObject && req === null) {
            try {
                req = new ActiveXObject("Msxml2.XMLHTTP");
                this.getTransport = function() {
                    return new ActiveXObject("Msxml2.XMLHTTP");
                };
            }
            catch(e1) {
                try {
                    req = new ActiveXObject("Microsoft.XMLHTTP");
                    this.getTransport = function() {
                        return new ActiveXObject("Microsoft.XMLHTTP");
                    };
                }
                catch(e2) {
                    req = false;
                }
            }
        }

        if (req === null) {
            this.getTransport = function() {
                return null;
            };
        }

        return this.getTransport();

    },

    makeAjaxCall : function(url, callback) {
        var xhr = this.getTransport();
        xhr.open("GET", url, true);
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                callback(xhr);
            }
        };
        xhr.send(null);
    }
    */
    //End of Bare Bones     
    

}

ncbi.sg.hasNotedErrorEvent = false;

(function(){

    //DO not bother runnning if not in the %
    if(!ncbi.sg.getInstance()._areEventsSG()){              
        return;
    }
    
    //JS ERROR REPORTING
    var oe = window.onerror;
    window.onerror = function(a,b,c){
        if(console && console.warn) console.warn("sg error to server to be investigated: \n" + a + "\n" + b + "\n" + c); 
        if(ncbi.sg.hasNotedErrorEvent){               
            if(console && console.info) console.info("Already found one error for this page, not sending another error report");
            return;
        }
        ncbi.sg.getInstance().noteEventData( "jserror", { "jserror": a, "jserrortype":b}, ["ncbi_sessionid"] );
        ncbi.sg.hasNotedErrorEvent = true;
        if(typeof oe === "function")return oe(a,b,c);
    }
    
        
    //CLICK EVENTS and LOAD TIME
    var ol = window.onload;
    window.onload = function( loadEvt ){

        if(typeof winOL1 === "funciton") winOL1( evt );
        var lnks = document.links;
        for(var i=0;i<lnks.length;i++){
            if(!lnks[i].onclick && !lnks[i].target){ 
                lnks[i].onclick = function(){ window.location.href = this.href; };
            }
        }

        if(typeof ol === "function"){
            ol( loadEvt );
        }
                
        //Used to fire events for the links and buttons after the event comes back
        function fireEvent( elem, meth ){
            if(!elem || !meth) return;
            if (document.createEventObject){
                elem.fireEvent('on' + meth, document.createEventObject());
            }
            else{
                var cEvt = document.createEvent("MouseEvents");
                cEvt.initEvent(meth, true, true );
                elem.dispatchEvent(cEvt);
            }
        }
        
        function reassignOnclick( elem ){
        
            if(!elem) return;

            //determine the elements click state and assign correct handler
            if(elem.onclick){
                elem.onclick_ = elem.onclick;
            }
            else if(elem.href){ 
                elem.onclick_ = function(){ 
                    window.location.href = elem.href;
                };
            }
            else{
                elem.onclick_ = function(){}
            }
        }
                
        function linkLoop(links, linkCurr, linkLen){
        
            var elem = links[linkCurr];
            
            if(elem){
                //If it opens up in a new window, we do not care how long it takes
                if(elem.target){ //NOTE if the link uses window.open, we need a target on it!!!
                    utils.addEvent(elem, "click", function(evt){ ncbi.sg.getInstance().noteLinkClickEventData(this);});                
                }
                else{
                    //reassign the onclick so we can override it
                    reassignOnclick( elem );
                
                    elem.onclick = function(evt){
                
                        //We got to stop the event from finishing
                        evt = evt || window.event;
                    
                        //Kill the click's bubbling
                        evt.cancelBubble = true; 
                        if (evt.stopPropagation) evt.stopPropagation();

                        //Callback so we can call the orginal onclick functionality
                        var callOrginalClick = function(){
                       
                            //swap it back because of Omn code
                            var dClick = elem.onclick;
                            elem.onclick = elem.onclick_;                        
                        
                            //elem.onclick.call(elem, evt);
                            fireEvent(elem,"click");
                        
                            //swap it back incase link does not go to another page
                            elem.onclick = dClick;
                                               
                        }
                    
                        if(elem.featured){
                            ncbi.sg.getInstance().noteFeaturedClickEvent( elem, callOrginalClick );
                        }
                        else{                    
                            ncbi.sg.getInstance().noteLinkClickEventData( elem, callOrginalClick );
                        }
                        elem.timer = window.setTimeout( callOrginalClick, 400);
                    
                        //cancel the click
                        return false; 
                    
                    }
                
                }
            
            }
            
            //Increment next link/button and repeat if necesscary 
            linkCurr++;
            if(linkCurr<linkLen){
                var nFnc = function(){ linkLoop(links, linkCurr, linkLen) };
                var t = window.setTimeout(nFnc,1); //This prevents browser lockup with looping
            }
            
        }

        //Links    
        var lnks = document.links;
        linkLoop( lnks, 0, lnks.length);
        
        //Buttons
        var btns = document.getElementsByTagName("button");
        linkLoop( btns, 0, btns.length ); 
                
        //load time
        if(typeof ncbi_startTime == "undefined") return;        
        var dt = new Date() - ncbi_startTime;
        ncbi.sg.getInstance().noteEventData( "loadtime", { "jsloadtime": dt}, ["ncbi_sessionid"] );
                                
    };
        
})();



if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}


Portal.Portlet.Entrez_DisplayBar = Portal.Portlet.extend({

	init: function(path, name, notifier) {
		console.info("Created DisplayBar");
		this.base(path, name, notifier);
		
		// save the original display/presentation value when page loads
		Portal.Portlet.Entrez_DisplayBar.originalPresentation = this.getValue("LastPresentation");
		console.info("Original Presentation is: " + Portal.Portlet.Entrez_DisplayBar.originalPresentation);
		
	},
	
	
	send: {
   
   		'PresentationChange': null,
		'TabCmd': null,
		'Cmd': null, 
		'PageSizeChanged': null
	},
	
	
	
	listen: {
		
		/* browser events */
			
		"sPresentation<change>": function(e, target, name){
			//get attribute values of selected option
			var dbfrom = target.options[target.selectedIndex].getAttribute('dbfrom');
			var dbto = target.options[target.selectedIndex].getAttribute('dbto');
			var cmd = target.options[target.selectedIndex].getAttribute('cmd');
			var readablename = target.options[target.selectedIndex].getAttribute('readablename');
			
			//call function to process
			this.ProcessPresentationChange(dbfrom, dbto, cmd, readablename, e, target, name);
		},
		
		
		"sPageSize<change>": function(e, target, name){		
			this.ProcessPageSizeChange(e, target, name);
		},
		
		
		"sSort<change>": function(e, target, name){
			this.ProcessSortChange(e, target, name);
		},
		
		
		"sSendTo<change>": function(e, target, name){
			var sendto = target.value;
			this.setValue("SendTo", sendto);
			
			this.SendToChanged(sendto, e, target, name); 
		},
		
		
		/* messages from message bus*/
		
		'Cmd' : function(sMessage, oData, sSrc) {
		    this.ProcessCmdChange(sMessage, oData, sSrc);
		},
		
		'ResetSendTo' : function(sMessage, oData, sSrc) {
			this.setValue("SendTo", oData.value);
				// reset sendto in selector
			var sSendToInputs = this.getInputs("sSendTo");
			for (var j = 0; j < sSendToInputs.length; j++){
				sSendToInputs[j].value = '';
			}
		},
		
		'newPresentation' : function(sMessage, oData, sSrc) {
			this.setValue("Presentation", oData.value);
		},
		
		'newPageSize' : function(sMessage, oData, sSrc) {
			this.setValue("PageSize", oData.value);
		},
		
		'newSort' : function(sMessage, oData, sSrc) {
			this.setValue("Sort", oData.value);
		}
	
	},
	
	ProcessPresentationChange: function(dbfrom, dbto, cmd, readablename, e, target, name) {		
		//send Cmd
		this.send.Cmd({
			'cmd': cmd
		});
		
		//Send link information and cmd
		this.send.PresentationChange({
			'dbfrom': dbfrom,
			'dbto': dbto,
			'linkname': target.value,
			'readablename': readablename
		});	
		
		// set Presentation
		this.setValue("Presentation", target.value);
	},
	
	
	ProcessPageSizeChange: function(e, target, name){
		//send Cmd
		this.send.Cmd({
			'cmd': target.getAttribute('cmd')
		});	
		//send PageSizeChanged
		this.send.PageSizeChanged({
			'size': target.value
		});	
		//set PageSize
		this.setValue("PageSize", target.value);
	},
	
	
	ProcessSortChange: function(e, target, name){
		//send Cmd
		this.send.Cmd({
			'cmd': target.getAttribute('cmd')
		});	
		//set Sort
		this.setValue("Sort", target.value);
	},
	
	
	SendToChanged: function(sendto, e, target, name) {
		if(sendto == 'Remove from Clipboard'){
			if(confirm('Are you sure you want to delete these items from Clipboard?')){
				this.send.Cmd({'cmd': sendto});
				document.forms[0].submit();
			}
			else{
				this.setValue("SendTo", '');
				// reset sendto in selector
				var sSendToInputs = this.getInputs("sSendTo");
				for (var j = 0; j < sSendToInputs.length; j++){
					sSendToInputs[j].value = '';
				}
			}
		}
		else if(sendto == 'File'){
			this.send.Cmd({'cmd': sendto});
		}
		else if(sendto == 'Mail'){
			this.send.Cmd({'cmd': sendto});
			this.send.TabCmd({'tab': 'E-mail'});
			document.forms[0].submit();
		}
		else if(sendto == 'My NCBI Collections'){
			this.send.Cmd({'cmd': sendto});
		}
		else if(sendto == ''){
			this.send.Cmd({'cmd': sendto});
		}
		else{
			this.send.Cmd({'cmd': sendto});
			document.forms[0].submit();
		}
	},
	
	'ProcessCmdChange': function(sMessage, oData, sSrc){
	    if (oData.cmd == 'PageChanged'){
			/* Reset Send To on page change to avoid sendto having previous value due to 
			using browser back button after viewing text format reports.*/
			this.setValue("SendTo", '');
				// reset sendto in selector
			var sSendToInputs = this.getInputs("sSendTo");
			for (var j = 0; j < sSendToInputs.length; j++){
				sSendToInputs[j].value = '';
			}
		}
		
		this.BackButtonCompatibilityForCmdChange(oData.cmd);
	},
	
	'BackButtonCompatibilityForCmdChange': function(cmd){
	    // for back button compatibility, keep presentation to old value for any cmds 
			// except when cmd indicates value was changed from DisplayBar.
		if (cmd != 'DisplayChanged' && cmd != 'Link' && cmd != 'SendMail'){
			// set Presentation
			this.setValue("Presentation", Portal.Portlet.Entrez_DisplayBar.originalPresentation);
		}
	}
},
{
	originalPresentation: ''
});


Portal.Portlet.Pubmed_DisplayBar = Portal.Portlet.Entrez_DisplayBar.extend({

	init: function(path, name, notifier) {
		console.info("Created inherited DisplayBar");
		this.base(path, name, notifier);
	},
	
	// need to add RSS to sSendTo
	SendToChanged: function(sendto, e, target, name) {
		if(sendto == 'RSS'){
			this.send.Cmd({'cmd': sendto});
			this.send.TabCmd({'tab': 'RSS Feed'});
			document.forms[0].submit();
		}
		else{
			 this.base(sendto, e, target, name);
		}
	}
});




/* 
   Handles 'Enter' key in Pager portlet.
   Requires: debug, utils, notify.
*/

Portal.Portlet.Pager = Portal.Portlet.extend ({

   init: function (path, name, notifier) 
   {		
		var oThis = this;
		this.base (path, name, notifier);

		console.info ("Created " + name);

   },
   
   
   send: {
   	'Cmd': null
   },
   
   
   listen: {
		// page events
   
		//"CurrPage<keypress>" : function(e, target, name){
		"PageNumber<keypress>" : function(e, target, name){
			if ((e.keyCode || e.which) == 13) {
console.info(target.value);
				// this.CheckPageNumber(this.getValue("CurrPage"));
				this.CheckPageNumber(target.value);
				// Emulate CurrPage action
				this.send.Cmd({'cmd': 'PageChanged'});
				document.forms[0].submit();  /// FIXME This is *evil*.
			}
		},
	
		"SetPage<click>" : function(e, target, name){
					
			//should be the first input of the target's parent (there are hidden inputs after)
			//also seems <em>kind of</em> *evil*  - eddie
			var newPage = target.parentNode.getElementsByTagName('input')[0].value;
			
			// this.CheckPageNumber(this.getValue("CurrPage"));
			this.CheckPageNumber(newPage);
			this.send.Cmd({'cmd': 'PageChanged'});
		},
		
		"Prev<click>" : function(e, target, name){
			// console.info ("CurrPage changed to: " + this.getValue("Prev:Page"));
			console.info ("CurrPage changed to: " + target.getAttribute('newPage'));
			this.send.Cmd({'cmd': 'PageChanged'});
			// this.setValue("CurrPage", this.getValue("Prev:Page"));
			this.setValue("CurrPage", target.getAttribute('newPage'));
		},
		
		"Next<click>" : function(e, target, name){
			// console.info ("CurrPage changed to: " + this.getValue("Next:Page"));
			console.info ("CurrPage changed to: " + target.getAttribute('newPage'));
			this.send.Cmd({'cmd': 'PageChanged'});
			// this.setValue("CurrPage", this.getValue("Next:Page"));
			this.setValue("CurrPage", target.getAttribute('newPage'));
		},
		
		// messages

		// when pagesize is changed, pager adjusts page number to keep displaying the start 
		// the start item of the initial page
		'PageSizeChanged' : function(sMessage, oData, sSrc) {
			if (this.getValue("CurrPage")){
				var start = (this.getValue("InitialPageSize") * 
						(this.getValue("CurrPage") - 1)) + 1;
				var newPage = parseInt((start - 1)/oData.size) + 1;
				this.setValue("CurrPage", newPage);
			}
		}

   },


  CheckPageNumber: function(page) { 
    var npage = parseInt(page); 
    var nmax = parseInt(this.getValue("MaxPage"));
    
    if (isNaN(npage) || isNaN(nmax) || npage <= 0 || npage > nmax) { 
        console.info("Invalid page number: " + page); 
        this.setValue("CurrPage", '1'); 
    } 
    else { 
        this.setValue("CurrPage", npage);
    } 
  }

});



Portal.Portlet.Entrez_RVBasicReport = Portal.Portlet.extend({
	
	init: function(path, name, notifier) {
		console.info("Created report portlet");
		this.base(path, name, notifier);
	},
	
	send: {
		'ItemSelectionChanged': null
	},
	
	listen: {
		"uid<click>" : function(e, target, name){
			this.send.ItemSelectionChanged( { 'id': target.value,
			                                  'selected': target.checked });
		}
	}
	
});
   

Portal.Portlet.Pubmed_RVDocSum = Portal.Portlet.Entrez_RVBasicReport.extend({
	
	init: function(path, name, notifier) {
		console.info("Created Pubmed_RVDocsum");
		this.base(path, name, notifier);
	}
});
   

Portal.Portlet.ResultsSearchController = Portal.Portlet.extend({

	init: function(path, name, notifier) {
		var oThis = this;
		console.info("Created ResultsSearchController");
		this.base(path, name, notifier);
	},	
		
	send: {
		'ResetSendTo': null,
		'LastQueryKey': null,
		'needSavedSelectedItemCount': null
	},
		
	listen: {
		
		/* messages from message bus*/
		
		'Cmd' : function(sMessage, oData, sSrc) {
			this.ProcessCmd(sMessage, oData, sSrc);
		},		
		
		// when result citations are selected, the list of selected ids are intercepted here
		'SelectedItemCountChanged' : function(sMessage, oData, sSrc){
			Portal.Portlet.ResultsSearchController.selectedItemCount = oData.count * 1;
		},
		
		// for SendTo File (processing after getting any initial selected item count from DbConnector)
		'SavedSelectedItemCount' : function(sMessage, oData, sSrc) {
			var SavedSelectedItemCount = oData.count;
			
			this.ProcessSavedSelectedItemCount(SavedSelectedItemCount, sMessage, oData, sSrc);
		},
		
		'RunLastQuery' : function(sMessage, oData, sSrc){
			if (this.getInput("RunLastQuery")){
				this.setValue ("RunLastQuery", 'true');
			}
		}
		
	},//listen
	
	ProcessCmd: function(sMessage, oData, sSrc){
    	Portal.Portlet.ResultsSearchController.cmd = oData.cmd;
	
		if (oData.cmd == 'Link'){
			if (this.getInput("LastQueryKey")){
				this.send.LastQueryKey({'qk': this.getValue("LastQueryKey")});
			}
		}
		else if (oData.cmd == 'File'){
			// asks for initial selected items count from dbconnector
			this.send.needSavedSelectedItemCount();
		}
		else if (oData.cmd == 'My NCBI Collections'){
			// asks for initial selected items count from dbconnector
			this.send.needSavedSelectedItemCount();
		}
	}, // ProcessCmd
	
	ProcessSavedSelectedItemCount: function(SavedSelectedItemCount, sMessage, oData, sSrc){
	    // get the count of items about to be processed 
	    var Count;
		if (Portal.Portlet.ResultsSearchController.selectedItemCount > 0){
			Count = Portal.Portlet.ResultsSearchController.selectedItemCount;
		}
		else if (SavedSelectedItemCount > 0){
			Count = SavedSelectedItemCount;
		}
		else{
			Count = this.getValue("ResultCount");
		}
		
	    if (Portal.Portlet.ResultsSearchController.cmd == 'My NCBI Collections'){
	        this.ProcessSavedItemsForCollections (Count, oData);
	    }
		else if (Portal.Portlet.ResultsSearchController.cmd == 'File'){
			this.ProcessSavedItemsForFile (Count, oData);
		}
	}, // ProcessSavedSelectedItemCount
	
	ProcessSavedItemsForCollections: function(Count, oData){
		// show message if item count is above limit
		if(Count > Portal.Portlet.ResultsSearchController.upperLimit){
		    // create message
			var message = "The maximum number of records that can be added to a My NCBI Collection is " 
			+ Portal.Portlet.ResultsSearchController.upperLimitText 
			+ ".\n"
			+ "Are you sure you want to save the first "
			+ Portal.Portlet.ResultsSearchController.upperLimitText
			+ " records to a Collection?\n";
			
			// if user confirms they want to add items, let them proceed to MY NCBI, otherwise cancel
    		if(confirm(message)){
    			Portal.requestSubmit(); 
    		}
    		else{
    			this.send.ResetSendTo({'value': ''});
    		}
		}
		else{
		    Portal.requestSubmit(); 
		}
		
	}, //ProcessSavedItemsForCollections
	
	ProcessSavedItemsForFile: function(Count, oData){
	    
		console.info("Count before send to file: " + Count);
		if (Count > Portal.Portlet.ResultsSearchController.upperLimit){
			if(confirm('Are you sure you want to download ' + Count + ' records?')){
				Portal.requestSubmit(); 
			}
			else{
				this.send.ResetSendTo({'value': ''});
			}
		}
		else{
			Portal.requestSubmit(); 
		}
	} //ProcessSavedItemsForFile

},
{
	selectedItemCount: 0,
	upperLimit: 5000,
	upperLimitText: '5,000',
	cmd: ''
});

Portal.Portlet.Pubmed_ResultsSearchController = Portal.Portlet.ResultsSearchController.extend({

	init: function(path, name, notifier) {
		console.info("Created derived ResultsSearchController");
		this.base(path, name, notifier);
	}
});
// makes an ext js looking portlet w/o using extjs
if (typeof(noext) == 'undefined') {
    noext = {};
}
noext.parseConfig = function(n) {
    var configStr = n.getAttribute('config') || '';
    try {
        var jsonObj = eval('({' + configStr + '})');
    }
    catch(e) {
        if (window.console) {
            console.error(e.message + ' in local config object in noext.Portlet: file: ' + e.fileName + ', line ' + e.lineNumber + '.' );
        }
    }
    return jsonObj;
};
noext.getClassArray = function(n) {
    var classNameStr = n.className;
    return classNameStr.split(' ');
};
noext.getFirstHeader = function(n) {
    var fc = utils.getFirstChild(n);
    if(fc.tagName.search(/^h\d/i) != -1) {
        return fc;
    }
};
noext.Portlet = function(n){
    this.n = n;
    this.headerNode = noext.getFirstHeader(this.n);
    this.headerDiv = document.createElement('div');
    this.bodyDiv = document.createElement('div');
    utils.addClass(this.bodyDiv, 'x-panel-body');
    var configObj = noext.parseConfig(this.n);
    this.collapsible = configObj.collapsible == false ? false : true; 
    this.closeable = configObj.closeable == false ? false : true; 
    this.collapsed = configObj.collapsed == true ? true : false;
    if (this.collapsed == true) {
        utils.addClass(this.n, 'x-panel-collapsed');
        this.bodyDiv.style.display = 'none';
    }
    this.make();
};

noext.Portlet.instances = [];
noext.Portlet.ready = function() {
    var nodes = $C('port', 'class', document, 'div');
    for (var i = 0; i < nodes.length; i++) {
        var n = nodes[i];
        if (utils.hasClass(n, 'norender')) {
            continue;
        }
        portlet = new noext.Portlet(n);
    }
}
noext.Portlet.prototype = {
    make: function() {
        // put a parent aruond body content
        //var innerContainingDiv = document.createElement('div');
        utils.addClass(this.n, 'x-panel');
        //this.n.style.width = 'auto';
        utils.addClass(this.headerDiv, 'x-panel-header');
        utils.addClass(this.headerDiv, 'x-unselectable');
        this.n.insertBefore(this.headerDiv, this.headerNode);
        var header = this.n.removeChild(this.headerNode);
        var toolCloseA = document.createElement('a');
        toolCloseA.setAttribute('href', '#');
        utils.addClass(toolCloseA, 'x-tool');
        utils.addClass(toolCloseA, 'x-tool-close');
        var toggleA = document.createElement('a');
        toggleA.setAttribute('href', '#');
        utils.addClass(toggleA, 'x-tool');
        utils.addClass(toggleA, 'x-tool-toggle');
        if (this.closeable == true) {
            this.headerDiv.appendChild(toolCloseA);
        }
        if (this.collapsible) {
            this.headerDiv.appendChild(toggleA);
        }
        this.headerDiv.appendChild(header);
        utils.addClass(this.headerNode, 'x-panel-header-text');
        this.toolCloseA = toolCloseA;
        this.toggleA = toggleA;
        this.reParent();
        this.setEvents();
    }, 
    reParent: function() {
        var bodyElems = [];
        utils.insertAfter(this.n, this.bodyDiv, this.headerDiv);
        for (var i = this.n.childNodes.length -1; i >= 0; i--) {
            var fc = this.n.childNodes[i];
            if (fc != this.headerDiv && fc != this.bodyDiv) { 
                bodyElems.push(this.n.removeChild(fc));
            }
            for (var j = 0; j < bodyElems.length; j++) {
                this.bodyDiv.appendChild(bodyElems[j]);
            }
        }
    },
    setEvents: function(toggleA) {
        var that = this;
        utils.addEvent(this.toggleA, 'click', function(e) { that.toggle(e)});
        utils.addEvent(this.toolCloseA, 'click', function(e) { that.close(e)});
    }, 
    toggle: function(e) {
        utils.preventDefault(e);
        if (utils.hasClass(this.n, 'x-panel-collapsed')) {
            utils.removeClass(this.n, 'x-panel-collapsed')
            this.bodyDiv.style.display = 'block';
        } else {
            utils.addClass(this.n, 'x-panel-collapsed');
            this.bodyDiv.style.display = 'none';
        }
    },
    close: function(e) {
        utils.preventDefault(e); 
        this.n.parentNode.removeChild(this.n);
    }
};

utils.addEvent(window, 'load', noext.Portlet.ready);

Portal.Portlet.HistoryDisplay = Portal.Portlet.extend({

	init: function(path, name, notifier) {
		console.info("Created History Ad...");
		this.base(path, name, notifier);
    
        // createDebugConsole(); // For debugging IE, of course.
		
		/* IE/Ext.Ncbi.Portlet problem. Some sort of race condition in IE only.
		   This delay ensures that popup initialization occurs last. */		
		
		//setTimeout(function() { //Fixed in Ext.Ncbi 1.5
			// Create ElementPopper for each li.query and li.record
			var elements = cssQuery("li.query, li.record");
			
			for (var i = 0; i < elements.length; i++) {
		       var elem = elements[i];
			   var c = cssQuery(".hidden", elem);
			   if (c && c.length > 0) {
			      var label = (c[0].textContent || c[0].innerText);
			      var cit = getCitation(elem);
			      /*
			      if (utils.hasClass(elem, "record")) {
				    label = "<i class='x'>View </i> " + label;
				  } else if (utils.hasClass(elem, "query")) {
				    label = "<i class='x'>Search </i>" + label;
				  }*/
				  
				  label = "<p id='htbpoptext'>" + label + "</p>";
				  if (cit && cit > ""){ // avoid "undefined" value
				      label = label + "<p id='htbpcit'>" + cit + "</p>";
				  }
			      new ElementPopper(elements[i], label);
			   }			   
			}
		//}, 1);
	},
	
	send: {
      'Cmd': null
      //'Recording': null
    },   
    
    receive: function(responseObject, userArgs) {    
         var cmd = userArgs.cmd;
         var rootNode = document.getElementById('HTDisplay');         
         var oldNode = document.getElementById('core'); //last.previousSibling;
         var msgNode = document.createElement("p");
         msgNode.setAttribute('id', 'core');
         rootNode.replaceChild(msgNode, oldNode);
         
         var txtNode;    
         var toggleLink = this.getInput('HistoryToggle');     
         if (cmd == 'HTOn') {             
             txtNode = document.createTextNode("Your browsing activity is empty.");
             toggleLink.innerHTML = 'Turn Off';
             toggleLink.textContent = 'Turn Off';   
             toggleLink.setAttribute('cmd', 'HTOff');  
             toggleLink.setAttribute('href', '?cmd=HTOff&'); 
             
             // hide "turn on" link
             var turnHTOn = $("turnOn"); 
             if (turnHTOn != null) {
                 turnHTOn.style.display = 'none';
             }
         }
         else if (cmd == 'HTOff') {             
             txtNode = document.createTextNode("Activity recording is turned off.");             
             toggleLink.innerHTML = 'Turn On';             
             toggleLink.setAttribute('cmd', 'HTOn');
             toggleLink.setAttribute('href', '?cmd=HTOn&'); 
             
             // show up "turn on" link
             var turnHTOn = $("turnOn"); 
             if (turnHTOn != null) {
                 turnHTOn.style.display = 'block';
             }             
         }
         else if (cmd == 'ClearHT') {
             var turnHTOn = $("turnOn"); 
             if (turnHTOn != null && turnHTOn.style.display == 'none') { // HT On
                 txtNode = document.createTextNode("Your browsing activity is empty.");
             }
             else { //HT Off
                 txtNode = document.createTextNode("Activity recording is turned off."); 
             }
         }
         msgNode.appendChild(txtNode);
            
    },
    
	listen: {
	  'Cmd' : function(sMessage, oData, sSrc){
			console.info("Inside Cmd in HistoryDisplay: " + oData.cmd);
			this.setValue("Cmd", oData.cmd);
	  },	  
		
      "HistoryToggle<click>" : function(e, target, name){
         //alert(target.getAttribute("cmd"));
         this.send.Cmd({'cmd': target.getAttribute("cmd")});         
         console.info("Inside HistoryToggle in HistoryDisplay: " + target.getAttribute("cmd"));
         
         var site = document.forms[0]['p$st'].value;
         var cmd =  target.getAttribute("cmd");     
         
         if (cmd.toUpperCase() == 'HTOFF') {
             //var popper = document.getElementById('htbpopper');
             //if (popper != undefined)
             var popper = cssQuery("div.popper");
             //alert(popper.length);
			 if (popper && popper.length > 0) {
			     for (var i = 0; i < popper.length; i++) {
                     popper[i].style.display = 'none';
                 }
             }
                 
         }
               
         // Issue asynchronous call to XHR service, callback is to update the portlet output
	     var resp = xmlHttpCall(site, this.path, cmd, {}, this.receive, {'cmd': target.getAttribute("cmd")}, this);
      }, 
      
      "HistoryOn<click>" : function(e, target, name){
         this.send.Cmd({'cmd': target.getAttribute("cmd")});
         //$PN('Pubmed_ResultsSearchController').getInput('RecordingHistory').value = 'yes';		 
         console.info("Inside HistoryOn in HistoryDisplay: " + target.getAttribute("cmd"));
                
         var site = document.forms[0]['p$st'].value;   
	     var resp = xmlHttpCall(site, this.path, "HTOn", {}, this.receive, {'cmd': target.getAttribute("cmd")}, this);
	     //Portal.requestSubmit();
      },
      
      "ClearHistory<click>" : function(e, target, name){
         this.send.Cmd({'cmd': target.getAttribute("cmd")});	
         
         var popper = document.getElementById('htbpopper');
         if (popper != undefined)             
             popper.style.display = 'none';
         
         var site = document.forms[0]['p$st'].value;   
	     var resp = xmlHttpCall(site, this.path, "ClearHT", {}, this.receive, {'cmd': target.getAttribute("cmd")}, this);	 
      }
    }
});

function getCitation(node) {
   // var withHistorys = cssQuery("*[title]", node); does not work!!!   
   var withTitles = $AN('title', node, '*');
   //alert(withTitles.length + " " + withTitles[0].tagName + " " + withTitles[withTitles.length-1].tagName);
   //alert(withTitles[1].getAttribute('title'));
   if (withTitles.length > 0) {      
      var p = withTitles[0];
      var s = p.getAttribute("title");
      if (s && s > "") { 
          //alert(s);
          p.setAttribute("title", "");
          node._title = s;
          for (var i = 0; i < withTitles.length; i++) {
              withTitles[i].removeAttribute("title");    
          }
      }
      /*else { //fixed in utils.js         
          s = node._title; // required for IE b/c of the bug in $AN
      }*/
   } else {
      s = node._title;
      //alert("old s "+ s);
   }
   return s;
}
//
// Java Module PopDiv_JS
//

//
// Shows and hides a div at a specific location, either (x,y), or relative to
// an element in a specific direction.
//
// Limitations:
//  - height or width must be set on the popper div, or it may not position correctly.
//
// You're probably better off using Popper instead of PopDiv for hover pops. Popper handles mouse events
// correctly.

var PopDiv = function(divId, className) {
   if (document.getElementById(divId)) {
      throw "PopDiv: element with id '" + divId + "' already exists in document";
   }
   this.div = document.createElement("div");
   this.div.id = divId;
   this.div.className = "popper";
   if (className) {
      this.div.className += " " + className;
   }
   
   this.innerdiv = document.createElement("div");
   this.innerdiv.className = "popperInnerDiv";
   
   document.body.appendChild(this.div);
   this.div.appendChild(this.innerdiv);
}

PopDiv.POP_ABOVE = 0;
PopDiv.POP_RIGHT = 1;
PopDiv.POP_BELOW = 2;
PopDiv.POP_LEFT = 3;
PopDiv.POP_CLASSES = ['pop-above', 'pop-right', 'pop-below', 'pop-left'];

PopDiv.POPPED = 'popped';
PopDiv.POP_GETXY = 'pop-getxy';

PopDiv.prototype = {
   // Show it at x, y
   showAt: function(html, x, y) {

      // Set content
      this.innerdiv.innerHTML = html;

      this.div.style.left = x + "px";
      this.div.style.top = y + "px";

      // Pop it
      utils.addClass(this.div, PopDiv.POPPED);

   },

   // Show it near element ("dir" indications direction)
   // Dimensions don't exist if element isn't shown.
   getXY: function() {
      var popped = utils.hasClass(this.div, PopDiv.POPPED);

      if (!popped) {
         utils.addClass(this.div, PopDiv.POPPED);
      }
      var dim = utils.getXY(this.div);
      if (!popped) {
         utils.removeClass(this.div, PopDiv.POPPED);
      }

      return dim;
   },

   hide: function() {
      utils.removeClass(this.div, PopDiv.POPPED);
      if (this.popClass) {
         utils.removeClass(this.div, this.popClass);
         this.popClass = null;
         this.popnode = null;
      }
   },

   // showBy shows a popper adjacent to another item.
   showBy: function(html, elem, dir) {
      var dx = dy = 0;

      // Already popped over a particular popnode
      if (this.popnode && (this.popnode == elem)) {
         return;
      }
      this.popnode = elem;

      // Default direction
      if (typeof(dir) != "number") {
         dir = PopDiv.POP_LEFT;
      }

      // Set class "pop-<direction>": this determines margin
      this.popClass = PopDiv.POP_CLASSES[dir];
      //console.info("dir = " + dir +", popclass = " + this.popClass);
      utils.addClass(this.div, this.popClass);

      // Get geometries of target and popper
      var thatdim = utils.getXY(elem);
      var popdim = this.getXY(this.div);
      //console.info(thatdim);
      //console.info(popdim);

      // Calculate position
      switch (dir) {
      case PopDiv.POP_ABOVE: dy = -1*popdim.h;  break;
      case PopDiv.POP_LEFT:  dx = -1*popdim.w;  break;
      case PopDiv.POP_BELOW: dy =    thatdim.h; break;
      case PopDiv.POP_RIGHT: dx =    thatdim.w; break;
      default:
        throw "PopDiv: Invalid direction: " + dir;
      }
      //console.info("Popping at: [x=" + (thatdim.x + dx) + ", y="+(thatdim.y + dy)+"]");

      this.showAt(html, thatdim.x + dx, thatdim.y + dy);
   }
};



// An ElementPopper shows a popup adjacent to a target element when the user mouses over the target.
// It handles browser events and manipulates a popper to show and hide detail data.
//
// When the mouse cursor enters the target, the content appears in the popper nearby.
//  When the mouse cursor leaves the target, the popper is hidden.
//
// This rather intense event handling code is necessary because mouseover and mouseout doesn't work
// as expected--mouseouts occur when moving over child nodes. The "relatedTarget" trick described
// by PPK (quirksmode.org) doesn't work either, because browsers sometimes drop events
// with related targets. So the only option is to capture document.onmousemove, and detect when
// the mouse either exits document.body, or moves over something that is neither the target nor
// one of its children.
//
// "popnode" is the target node
// "content" is either a string (the content to show), a DOM node (show its innerHTML), or a function.
// "direction" is PopDir.POP_*, defined above; default POP_LEFT
// "divId" is the ID to assign to the popper; default is to make one up.
//
// When used with Ext.Ncbi, the popper should initialize itself on the page a few hundred
// ms after the page loads. IE apparently creates a race condition where popper and Ext.Ncbi initialization
// throw away the event handlers on which ElementPopper depends.
//
// So in that case, instead of new ElementPopper(a,b), you want to do:
//     setTimeout(function() {new ElementPopper(a,b);}), 500);

//
var ElementPopper = function(popnode, content, direction, divId) {

    var that = this;

    // Inner functions
    // If target is popnode or one of its children, returns popnode; otherwise, null
    function getPopTarget(target) {
       while (target && !utils.hasClass(target, "popnode")) {
          target = target.parentNode;
       }
       return target;
    };

    // Use inner functions here because removeEvent requires a reference to the
    // function object passed to addEvent, and we need to use closure to maintain scope.

    // Show popper and start tracking mouse motions
    var doPop = function(e) {
       var target = getPopTarget(utils.getTargetObj(e));
       
       // Pop, shift listener to document body
       if (target) {
          that.thePopper.showBy(that.contentFunction(), target, that.direction);

          utils.removeEvent(target, "mousemove", doPop);
          utils.addEvent(document.body, "mousemove", trackMouse);
          utils.addEvent(document.body, "mouseout", trackMouse);
       }
    };

    // Unpop, shift listener back to popnode
    var trackMouse = function(e) {
       var target = getPopTarget(utils.getTargetObj(e));

       // If mouse left document.body, or the target's not over the popnode, hide.
       if (e.type == "mouseout" || target == null) {
          that.thePopper.hide();
          utils.removeEvent(document.body, "mousemove", trackMouse);
          utils.removeEvent(document.body, "mouseout", trackMouse);
          utils.addEvent(popnode, "mousemove", doPop);
       }
    };

    // END inner functions

    // If content is a string, make it a function that returns the string.
    // If it's a dom node, make it a function that returns the dom node's innerHTML
    if (typeof(content) == 'string') {
       this.contentFunction = function() { return content; }
    } else if (content.innerHTML) {
       this.contentFunction = function() { return content.innerHTML; }
    } else {
       this.contentFunction = content; // Better be a function...
    }

    this.direction = direction;

    // Create the popper
    this.popperId = divId || ("popper" + (ElementPopper.popIndex++));
    this.thePopper = new PopDiv(this.popperId);

    // Get popnode if it's an id string
    if (typeof(popnode) == 'string') {
        popnode = $(popnode);
        if (!popnode) {
           throw "ElementPopper: id not found";
        }
    }

    // When the user mouses over target, pop it up
    utils.addEvent(popnode, "mousemove", doPop);
}

ElementPopper.popIndex = 0;



Portal.Portlet.FilterTab = Portal.Portlet.extend({
	
	init: function(path, name, notifier) {
		console.info("Created FilterTab");
		this.base(path, name, notifier);
	},
	
	send: {
		'Cmd': null,
		'AppendTerm': null,
		'ClearIdList': null
	},
	
	listen: {
			//browser events
		"Tab<click>" : function(e, target, name){
			this.send.Cmd({'cmd': 'FilterChanged'});
			this.setValue("CurrFilter", target.getAttribute('filter'));
			console.info("CurrFilter changed to: " + this.getValue('CurrFilter'));
		},
		
		"Pin<click>" : function(e, target, name){
		    // sets filter to all, simulates Go command - sets the term and checks for original db through search bar
			this.send.Cmd({'cmd': 'Go'});
			newTerm = '\"' + target.getAttribute('filter') + '\"[Filter]';
			this.send.AppendTerm({'op' : 'AND', 'term': newTerm});
			this.setValue("CurrFilter", 'all');
			//for back button compatibility, clear any selected ids.
			this.send.ClearIdList();
		},


			// messages
		// back button fix
		'Cmd' : function(sMessage, oData, sSrc){
			if (oData.cmd != 'FilterChanged'){
				if(this.getValue("CurrFilter") != this.getValue("LastFilter")){
					this.setValue("CurrFilter", this.getValue('LastFilter'));
					console.info("CurrFilter changed to: " + this.getValue('CurrFilter'));
				}
			}
		}


	}
	
});
   


/* 
   Based on /entrez/query/PubMed/limits.js, refactored for 
   compatibility with Portal client-side JS programming framework
   Requires: debug, utils, notify.
*/

Portal.Portlet.Pubmed_LimitsTab = Portal.Portlet.extend ({

   init: function (path, name, notifier) 
   {		
	    this.m_suggestions = new Array;
	    this.m_bSubmitSkip = false;
   
		var oThis = this;
		this.base (path, name, notifier);

		console.info ("Created " + name);

		// Check if current Tab is indeed Limits before going any further	
		var curTab = this.getInput ('CurrentTab');					
		if (curTab && curTab.value == 'Limits')	
		{				
			var pLimitSel = this.getInput ('pmfilter_PDatLimit');
			if (pLimitSel)
			{
				utils.addEvent (pLimitSel, "change", 
								function (e)
								{
									oThis.OpenSpecDates ('PDatesSel');
								}, true);					  
			}
			var eLimitSel = this.getInput ('pmfilter_EDatLimit');
			if (eLimitSel)
			{
				utils.addEvent (eLimitSel, "change", 
								function (e)
								{
									oThis.OpenSpecDates ('EDatesSel');
								}, true);		
			}
			this.CheckDateRange ('PDatesSel', 'PDatRange');			  
			this.CheckDateRange ('EDatesSel', 'EDatRange');		
			
			console.info ("Initialized " + name);
		}			
   },
   
   beforesubmit: function ()
   {
		var curTab = this.getInput ('CurrentTab');					
		if (curTab && curTab.value == 'Limits')	
			this.CollectLimits ();
		return false;
   },
   
   SetSuggestion: function (fieldId, sSuggestion)
   {
   		this.m_bSubmitSkip = true;
		this.m_suggestions[fieldId] = sSuggestion;
   },
  
   GetSuggestion: function (fieldId)
   {
		return this.m_suggestions[fieldId];
   },
  
   CollectLimits: function ()
   {
		var a = $("auth_dd");
		if (a != null) 
			this.AddToQuery ('author_', 'Auth', 'pmfilter_AuthOp', 'AND', false);
		var j = $("journ_dd");
		if (j != null) 
			this.AddToQuery ('journ_', 'Jour', '', 'OR', true);
   },
   
   AddToQuery: function (id, field, selector, defval, quotation)
   {
		if (!document.getElementsByTagName || !document.getElementById) 
			return; 
		var ln = id.length;
		var query_add = "";
		var op = "";
		var operation = this.SelectorValue (selector, defval);
		var inps = document.getElementsByTagName ("INPUT")
		for (var i = 0; i < inps.length; i++) 
		{
			var thisNode = inps[i];
			if (thisNode.type.toUpperCase() == "TEXT" ) 
			{
				var thisId = thisNode.id;
				var s1 = thisId.substring (ln, -ln), s2 = thisId.substring (ln);
				if ((id == s1) && (s2.match (/[0-9]+/))) 
				{
					var v = thisNode.value;
					if ((v.length > 0) && (!v.match (/~[\s]*$/))) 
					{
						var tquot = quotation;
						if (tquot) 
						{
							if (this.GetSuggestion (thisId) != v) 
								tquot = false;
						}
						if (tquot)
							query_add = query_add + op + '"' + v + '"[' + field + ']';
						else
							query_add = query_add + op + v + '[' + field + ']';
						if (!(op.length > 0))
							op = " " + operation + " ";
					}
				}
			}
		}
		
		if (query_add.length > 0) 
	        this.notifier.Notify (this, 'TermLogicalOp', { 'op': 'AND', 'key': query_add });
	},
	
	SelectorValue : function (sname, defval)
	{
		if (!document.getElementsByName || !document.getElementById) 
			return; 
		var value = defval;
		if (!value.length > 0) 
			value = "AND";

		if ( sname.length > 0 ) 
		{
			var cbs = $N(sname);		  
			for (var i = 0; i < cbs.length; i++) 
			{
				var thisNode = cbs[i];
				if (thisNode.type.toUpperCase() == "RADIO" ) 
				{
					if (thisNode.checked) 
					{
						value = thisNode.value;
						return value;
					}
				}
			}
		}
		return value;
	},
	
	OpenSpecDates: function (PSelectId) 
	{
		var node = $(PSelectId);
		var divblock = $(PSelectId + "Block");
		if (!node || !divblock)
		    return;
		if (node.value == "daterange") 
		{ 
			divblock.shown = true
			divblock.style.display = "block"
			enableInputs (divblock, true);
		} 
		else 
		{
			divblock.shown = false
			divblock.style.display = "none"
			enableInputs (divblock, false);
			this.ClearDateRangeBlock (PSelectId + "Block");
		}
	},

	CheckDateRangeBlock: function (blockid, rangename)
	{
		if (!document.getElementsByTagName || !document.getElementById)  
			return false;
		  
		var pm = this.path + ".pmfilter_" + rangename;
		var ef = ["_MinYear", "_MinMonth", "_MinDay", "_MaxYear", "_MaxMonth", "_MaxDay"];
		var efl= [ef[0].length, ef[1].length, ef[2].length, ef[3].length, ef[4].length, ef[5].length ];

		var node = $(blockid);
		if (!node) 
			return false;
		  
		var inps = node.getElementsByTagName("INPUT")
		for (var i = 0; i < inps.length; i++) 
		{
			var thisNode = inps[i];
			if (thisNode.type.toUpperCase() == "TEXT") 
			{
				var thisName = thisNode.name;
				if (thisName.indexOf (pm) == 0) 
				{
					var l = thisName.length;
					for (j = 0; j < 6; j++) 
					{
						if (thisName.slice (l - efl[j]) == ef[j]) 
						{
							if (thisNode.value.length > 0) 
								return true;
						}
					}
				}
			}
		}  
		return false;
	},

	CheckDateRange: function (selectid, rangename) 
	{
		var node = $(selectid);
		if (!node)
		    return;
		if (this.CheckDateRangeBlock (selectid + "Block", rangename)) 
		{
			node.value = "daterange";
			this.OpenSpecDates (selectid);
		}
		else if (node.value == "daterange")
			node.value = "any";
	},

	ClearDateRangeBlock: function (blockid)
	{
		if (!document.getElementsByTagName || !document.getElementById) 
			return false; 
	  
		var pm = this.path + ".pmfilter_";
		var ef = ["_MinYear", "_MinMonth", "_MinDay", "_MaxYear", "_MaxMonth", "_MaxDay"];
		var efl= [ef[0].length, ef[1].length, ef[2].length, ef[3].length, ef[4].length, ef[5].length ];
		  
		var node = $(blockid);
		if (!node)
			return;
		  
		var inps = node.getElementsByTagName ("INPUT");
		for (var i = 0; i < inps.length; i++) 
		{
			var thisNode = inps[i];
			if (thisNode.type.toUpperCase() == "TEXT" ) 
			{
				var thisName = thisNode.name;
				if (thisName.indexOf (pm) == 0) 
				{
					var l = thisName.length;
					for (j = 0; j < 6 ; j++) 
					{
						if (thisName.slice (l - efl[j]) == ef[j])
							thisNode.value = '';
					}
				}
			}
		}		  
		return false;
	},
	
	ClearAllDates: function ()
	{
		this.SetSelectorValue ('pmfilter_PDatLimit', 'any');
		this.OpenSpecDates ('PDatesSel');
		this.SetSelectorValue ('pmfilter_EDatLimit', 'any');
		this.OpenSpecDates ('EDatesSel');
		return false;
	},
	
	ClearAll: function ()
	{
		rem_rows ('auth_dd');
		showhide ('AuthBlock', true, '' , 'hide');
		rem_rows ('journ_dd');
		showhide ('JourBlock', true, '' , 'hide');
		this.ClearAllDates ();
		setAll ('simsearch', false); 
		setAll ('hum_ani', false); 
		setAll ('gender', false); 
		setAll ('lang', false); 
		setAll ('subs', false); 
		setAll ('pubt', false); 
		setAll ('ages', false); 
		this.SetSelectorValue ('LimitsField', 'All Fields');
		return false;
	},
	
	SetSelectorValue: function (sname, svalue)
	{
	   var sel = this.getInput (sname);
	
	   if (sel) 
	   {
		  for (i = 0; i < sel.options.length; ++i) 
		   sel.options[i].selected = sel.options[i].value == svalue;
	   }
	   return false;
	},
	
	SubmitOnEnterKey: function (id)
	{
		var oThis = this;
	    var el = $(id);
	    if (el)
	    {
/*	        utils.addEvent (el, "keypress", 
	                        function (event, target, name) 
	                        {
	                        	 event = event || utils.fixEvent (window.event);
	                             if ((event.keyCode || event.which) == 13)		
	                             {						  
									 if (NSuggest_IsActive () == null && oThis.m_bSubmitSkip == false)
									 {	
										 event.returnValue = false;
		                              	 event.stopPropagation ();   
		                              	 event.preventDefault ();   
		                                 Portal.$send('LimitsGoClicked',  {});		                                 
		                             }
									 oThis.m_bSubmitSkip = false;
	                             }
	                        }, true);               */

			// TODO: replace by utils.addEvent call once it's fixed by Sergey Ponomarev
	        addEvent2 (el, "keypress", 
	                        function (event, target, name) 
	                        {
								 event = event || utils.fixEvent (window.event);
	                             if ((event.keyCode || event.which) == 13)		
	                             {						  
									 if (NSuggest_IsActive () == null && oThis.m_bSubmitSkip == false)
									 {
										 event.returnValue = false;
										 if (event.stopPropagation != undefined)
			                              	 event.stopPropagation ();   
										 if (event.preventDefault != undefined)
		                              	 	event.preventDefault ();   
		                                 Portal.$send('LimitsGoClicked',  {});		                                 
									 }
									 oThis.m_bSubmitSkip = false;
	                             }
	                        }, true);               
	    }
	  
	},    	
	    
   send: {
   	"LimitsGoClicked": null
   },


   listen: {
	  "LimitsGo<click>": function(e, target, name) {
          this.send.LimitsGoClicked ();
	  },
	  
	  "ClearAll<click>": function(e, target, name) { 
	      this.ClearAll();
	  },
	  
	  "ClearAll<keypress>": function(e, target, name) { 
	      if ((e.keyCode || e.which) == 13) {
	          this.ClearAll();
	      }
	  }         
   }

});

// Clear all checkboxes inside target node
function setAll(nodeName, value) {
   if (!document.getElementById) return false
   var node= document.getElementById(nodeName)

   if (node) {
      var cbs = node.getElementsByTagName("INPUT")
      for (var i = 0; i < cbs.length; i++) {
         var cb = cbs[i]
         if (cb.getAttribute("TYPE").toUpperCase() == "CHECKBOX") {
            cb.checked = value
         } else {
         cb.value = ""; 
		 }
      }
   }
   return false;
}

function enableInputs(node, enabled) {
   var kinput, kid
   var kids
   var kinputArray = ["button", "input", "optgroup", "option", "select", "textarea"];
//   alert(enabled +" " +node.tagName)
   for (kinput in kinputArray) {
      kids = node.getElementsByTagName(kinputArray[kinput])
//	  alert (kids.length)
	  for (var i = 0; i < kids.length; i++) {
	     kid = kids[i]
		 kid.disabled = !enabled
      }
   }
}

// Show and hide a target node. If the second argument is true,
// then disable (enable) all child inputs 

larrow_closed=new Image(1,1);
larrow_closed.src="/corehtml/query/PubMed/gifs/close_arrow.gif";
larrow_open=new Image(1,1);
larrow_open.src="/corehtml/query/PubMed/gifs/open_arrow.gif";

function openAllBlocks() {
 showhide('AuthBlock', true, 'auth_image', 'show');
 showhide('JourBlock', true, 'journ_image', 'show');
 showhide('AbstrBlock', true, 'abstr_image', 'show');
 showhide('DatesBlock', true, 'dates_image', 'show');
 showhide('HumAnimBlock', true, 'ha_image', 'show');
 showhide('GenderBlock', true, 'gender_image', 'show');
 showhide('LangBlock', true, 'lang_image', 'show');
 showhide('SubsetsBlock', true, 'subset_image', 'show');
 showhide('PublicTypeBlock', true, 'publictype_image', 'show');
 showhide('AgesBlock', true, 'ages_image', 'show');
 showhide('TermsBlock', true, 'terms_image', 'show');
}

function showhide(target, disableChildren, image_id , todo) {
   var node = document.getElementById(target)
   if (!node) { return false }
//   if (todo) node.shown=(todo? "hide": "show")?false:true;
	if (todo == "hide") { node.shown = true; }
	if (todo == "show") { node.shown = false; }

   if (node.shown) {
      node.shown = false
      node.style.display = "none"
	  if (image_id) document.getElementById(image_id).src = larrow_open.src;
	  if (disableChildren) {
	  	enableInputs(node, false);
	  }
   } else {
      node.shown = true
      node.style.display = "block"
	  if (image_id) document.getElementById(image_id).src = larrow_closed.src;
	  if (disableChildren) {
	     enableInputs(node, true);
      }
   }
   return false
}

var newRowsAuthor = 0;
var newRowsJournal = 0;
var newRowsCounter = 0;

// remrow
// Remove the same row in the table where "obj" sits

function remrow(event)		// if presents row will not removed but hided with display:none
{

      var target;
            if (event) {  // mozilla et al
                target = event.target;
            } else {  // IE
                event = window.event;
				target = event.srcElement;
            }
	if (target.myrow) {
		var trparent = target.myrow.parentNode;
		trparent.removeChild(target.myrow);
		if (target.lable == "Author") newRowsAuthor--; 
		if (target.lable == "Journal") newRowsJournal--;
	}
	if (newRowsAuthor == 0) { showhide('AuthBlock', true, '' , 'hide'); } 
	if (newRowsJournal == 0) { showhide('JourBlock', true, '' , 'hide'); }
	return false;
}

function rem_rows(blockid)
{
	
	var tbtarget = document.getElementById(blockid).getElementsByTagName("tbody")[0];
	if (tbtarget) {
        var tbody = document.createElement('tbody');
        var tbparent = tbtarget.parentNode;
        tbparent.removeChild(tbtarget);    
        tbparent.appendChild(tbody);
    }
	if (blockid == "auth_dd") { Author_Count=0;  newRowsAuthor=0;  }
	if (blockid == "jour_dd") { Journal_Count=0; newRowsJournal=0; }

}

// addrow

function addrow(tab, lable) {
	newRowsCounter++;
	if (lable == "Author") { newRowsAuthor++; newRowsCounter = newRowsAuthor; }
	if (lable == "Journal") { newRowsJournal++; newRowsCounter = newRowsJournal; }
	
	var src  = document.getElementById(tab).getElementsByTagName("tfoot")[0].getElementsByTagName("tr")[0];
	var dest = document.getElementById(tab).getElementsByTagName("tbody")[0];
	var srcopy = src.cloneNode(true);
	retainNames (srcopy.getElementsByTagName("input"));
	dest.appendChild(srcopy);
	
	// Assume the "remove" tag is the first and only link in the <tr></tr>
	var alink = srcopy.getElementsByTagName("a");
	
	if (alink) {
	   alink = alink.item(0);
	   alink.myrow = srcopy;
	   alink.lable = lable;
	   alink.onclick = remrow;
	}


	if (typeof suggest == "object") suggest.load();
    
//	return false;
}


// retainNames
// Function adds numeric suffixes to every element that has name parameter. Numeric will suffix follow after "--"

function retainNames (rowcopyFields) {
	for (var i=0; i < rowcopyFields.length; i++) {
		var theName = rowcopyFields[i].name 
		if (theName) {
			if (rowcopyFields[i].type == "radio") {
				rowcopyFields[i].value = theName + newRowsCounter;
			} else {
				rowcopyFields[i].name = theName + newRowsCounter;
				rowcopyFields[i].id = theName +  newRowsCounter;  // IE can't find just created elements by name, so it needs ID.
			}
		}
	}
}

function SetFocus( focusname ) 
{
    if (document.getElementById) {
      var el = document.getElementById( focusname );
      if ( typeof el == "object" ) { 
        el.focus(); 
      }
    }
}

function select_focus(id) { 
    var field = document.getElementById(id)
    date_s = "YYYYMMDD"
    if (date_s.indexOf(field.value) != -1) field.select();
}

//TODO: move to utils class by Sergey Ponomarev
function addEvent2( obj, type, fn ) {
    if (obj.addEventListener) {
        obj.addEventListener( type, fn, false );
        EventCache.add(obj, type, fn);
    }
    else if (obj.attachEvent) {
        obj["e"+type+fn] = fn;
        obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
        obj.attachEvent( "on"+type, obj[type+fn] );
        EventCache.add(obj, type, fn);
    }
    else {
        obj["on"+type] = obj["e"+type+fn];
    }
}

var EventCache = function(){
    var listEvents = [];
    return {
        listEvents : listEvents,
        add : function(node, sEventName, fHandler){
            listEvents.push(arguments);
        },
        flush : function(){
            var i, item;
            for(i = listEvents.length - 1; i >= 0; i = i - 1){
                item = listEvents[i];
                if(item[0].removeEventListener){
                    item[0].removeEventListener(item[1], item[2], item[3]);
                };
                if(item[1].substring(0, 2) != "on"){
                    item[1] = "on" + item[1];
                };
                if(item[0].detachEvent){
                    item[0].detachEvent(item[1], item[2]);
                };
                item[0][item[1]] = null;
            };
        }
    };
}();
addEvent2(window,'unload',EventCache.flush);
Portal.Portlet.MessageBar = Portal.Portlet.extend ({
	init: function (path, name, notifier)
	{
		this.base (path, name, notifier);
	},
	
	send: {
		"TabCmd": null,
		"Cmd": null,
		"Term": null
	},
	
	listen: {
		//upon clicking 'see details', sends name of details tab.
		"Details<click>":  function(e, target, name) {
			this.send.TabCmd({'tab': this.getValue("Details:tab")});
		},
		
		"CorrectedQuery<click>": function(e, target, name) {
		    this.send.Term ({'term': target.getAttribute('term')})
		    this.send.Cmd ({'cmd': 'CorrectSpelling'})
		}
	}
});


Portal.Portlet.SearchController = Portal.Portlet.extend({
   
   init: function(path, name, notifier) {
      console.info("Created SearchController");
      this.base(path, name, notifier);
   },
   
   listen: {
   
		'QueryKey' : function(sMessage, oData, sSrc) {
			this.ReceivedQueryKey(sMessage, oData, sSrc);
		},
        
        'scTerm' : function(sMessage, oData, sSrc) {
			this.ReceivedTerm(sMessage, oData, sSrc);
        }
    },
   
    ReceivedQueryKey : function (sMessage, oData, sSrc){
       this.setValue('QueryKey', oData.qk);
    },
   
    ReceivedTerm : function (sMessage, oData, sSrc){
       this.setValue('Term', oData.term);
    }
});

Portal.Portlet.Pubmed_SearchController = Portal.Portlet.SearchController.extend({
   
   init: function(path, name, notifier) {
      this.base(path, name, notifier);
   }
 
});
Portal.Portlet.CommandTab = Portal.Portlet.extend ({
	init: function (path, name, notifier)
	{
		 console.info ("Created CommandTab");
		this.base (path, name, notifier);
	},
	
	send: {
		"Cmd": null,
		"TabCmd": null
	},
	
	listen: {
		//upon click on tab, sends name of tab that was clicked,
		// and the command that indicates that a tab was clicked.
		"Tab<click>":  function(e, target, name) {
			this.send.TabCmd({'tab': target.getAttribute("tab")});
			this.send.Cmd({'cmd': 'CommandTabClicked'});
		},
		
	
		"LimitCheckBox<click>":  function(e, target, name) {
			console.info ("LimitsActive: " + this.getValue("LimitsActive"));
			if (target.checked){
				this.setValue("LimitsActive", 'true');
				console.info ("LimitsActive: " + this.getValue("LimitsActive"));
			}
			else{
				this.setValue("LimitsActive", 'false');
				console.info ("LimitsActive: " + this.getValue("LimitsActive"));
			}
				
		},
		
		'PreserveTabCmd' : function(e, target, name) {
			this.send.TabCmd({'tab': this.getValue("LastTabCmd")});	
		}
	}
});

Portal.Portlet.Pubmed_CommandTab = Portal.Portlet.CommandTab.extend ({
	init: function (path, name, notifier)
	{
		console.info ("Created Pubmed_CommandTab");
		this.base (path, name, notifier);
	}
});
Portal.Portlet.DbConnector = Portal.Portlet.extend({

	init: function(path, name, notifier) {
		var oThis = this;
		console.info("Created DbConnector");
		this.base(path, name, notifier);
     
		// the SelectedIdList and id count from previous iteration
		Portal.Portlet.DbConnector.originalIdList = this.getValue("LastIdsFromResult");
		console.info("originalIdList " + Portal.Portlet.DbConnector.originalIdList);
		// if there is an IdList from last iteration set the count
		if (Portal.Portlet.DbConnector.originalIdList != ''){
			Portal.Portlet.DbConnector.originalCount = Portal.Portlet.DbConnector.originalIdList.split(/,/).length;
		}

		notifier.setListener(this, 'HistoryCmd', 
        	function(oListener, custom_data, sMessage, oNotifierObj) {
           		var sbTabCmd = $N(oThis.path + '.TabCmd');
           		sbTabCmd[0].value = custom_data.tab;
        	}
    		, null);
    
	},

	send: {
   		'SelectedItemCountChanged': null,
   		'newUidSelectionList': null,
   		'SavedSelectedItemCount': null
	},

	listen: {
	
		//message from Display bar on Presentation change 
		'PresentationChange' : function(sMessage, oData, sSrc){
			
			// set link information only if it exists
			if (oData.dbfrom){
				console.info("Inside PresentationChange in DbConnector: " + oData.readablename);
				this.setValue("Db", oData.dbto);
				this.setValue("LinkSrcDb", oData.dbfrom);
				this.setValue("LinkName", oData.linkname);
				this.setValue("LinkReadableName", oData.readablename);
			}
			//document.forms[0].submit();
		},
		
		// various commands associated with clicking different form control elements
		'Cmd' : function(sMessage, oData, sSrc){
			console.info("Inside Cmd in DbConnector: " + oData.cmd);
			this.setValue("Cmd", oData.cmd);
			
			// back button fix, clear TabCmd
			if (oData.cmd == 'Go' || oData.cmd == 'PageChanged' || oData.cmd == 'FilterChanged' || 
			oData.cmd == 'DisplayChanged' || oData.cmd == 'HistorySearch' || oData.cmd == 'Text' || 
			oData.cmd == 'File' || oData.cmd == 'Printer' || oData.cmd == 'Order' || 
			oData.cmd == 'Add to Clipboard' || oData.cmd == 'Remove from Clipboard' || 
			oData.cmd.toLowerCase().match('details')){
				this.setValue("TabCmd", '');
				console.info("Inside Cmd in DbConnector, reset TabCmd: " + this.getValue('TabCmd'));
			}

		},
		
		
		// the term to be shown in the search bar, and used from searching
		'Term' : function(sMessage, oData, sSrc){
			console.info("Inside Term in DbConnector: " + oData.term);
			this.setValue("Term", oData.term);
		},
		
		
		// to indicate the Command Tab to be in
		'TabCmd' : function(sMessage, oData, sSrc){
			console.info("Inside TABCMD in DbConnector: " + oData.tab);
			this.setValue("TabCmd", oData.tab);
			console.info("DbConnector TabCmd: " + this.getValue("TabCmd"));
		},
		
		
		// message sent from SearchBar when db is changed while in a Command Tab
		'DbChanged' : function(sMessage, oData, sSrc){
			console.info("Inside DbChanged in DbConnector");
			this.setValue("Db", oData.db);
		},
		
		// Handles item select/deselect events
		// Argument is { 'id': item-id, 'selected': true or false }
		'ItemSelectionChanged' : function(sMessage, oData, oSrc) {
			var sSelection = this.getValue("IdsFromResult");
			var bAlreadySelected = (new RegExp("\\b" + oData.id + "\\b").exec(sSelection) != null);
	       	var count =0;
	       	
			if (oData.selected && !bAlreadySelected) {
				sSelection += ((sSelection > "") ? "," : "") + oData.id;
			   	this.setValue("IdsFromResult", sSelection);
			   	if (sSelection.length > 0){
			   		count = sSelection.split(',').length;
			   	}
			   	this.send.SelectedItemCountChanged({'count': count});
			   	this.send.newUidSelectionList({'list': sSelection});
		   	} else if (!oData.selected && bAlreadySelected) {
				sSelection = sSelection.replace(new RegExp("^"+oData.id+"\\b,?|,?\\b"+oData.id+"\\b"), '');
		   	   	this.setValue("IdsFromResult", sSelection);
				console.info("Message ItemSelectionChanged - IdsFromResult after change:  " + this.getValue("IdsFromResult"));
			   	if (sSelection.length > 0){
			   		count = sSelection.split(',').length;
			   	}
				console.info("Message ItemSelectionChanged - IdsFromResult length:  " + count);   
				this.send.SelectedItemCountChanged({'count': count});
			   	this.send.newUidSelectionList({'list': sSelection});
		   	}
		},
				
		// FIXME: This is the "old message" that is being phased out.
		// when result citations are selected, the list of selected ids are intercepted here,
		// and notification sent that selected item count has changed.
		'newSelection' : function(sMessage, oData, sSrc){
		
			// Check if we already have such IDs in the list
			var newList = new Array();
			var haveNow = new Array();
			if(Portal.Portlet.DbConnector.originalIdList){
				haveNow = Portal.Portlet.DbConnector.originalIdList.split(',');
				newList = haveNow;
			}
			
			var cameNew = new Array();
			if (oData.selectionList.length > 0) {
				cameNew = oData.selectionList;
			}
			
			if (cameNew.length > 0) {
				for(var ind=0;ind<cameNew.length;ind++) {
					var found = 0;
					for(var i=0;i<haveNow.length;i++) {
						if (cameNew[ind] == haveNow[i]) {
							found = 1;
							break;
						}
					}
						//Add this ID if it is not in the list
					if (found == 0) {
						newList.push(cameNew[ind]);
					}
				}
			}
			else {
				newList = haveNow;
			}

				// if there was an IdList from last iteration add new values to old
			var count = 0;
			if ((newList.length > 0) && (newList[0].length > 0)){
				count = newList.length;
			}
			
			console.info("id count = " + count);
			this.setValue("IdsFromResult", newList.join(","));
			
			this.send.SelectedItemCountChanged({'count': count});
			this.send.newUidSelectionList({'list': newList.join(",")});
		},


		// empty local idlist when list was being collected for other purposes.
		//used by Mesh and Journals (empty UidList should not be distributed, otherwise Journals breaks)
		'ClearIdList' : function(sMessage, oData, sSrc){
			this.setValue("IdsFromResult", '');
			this.send.SelectedItemCountChanged({'count': '0'});
			this.send.newUidSelectionList({'list': ''});
		}, 


		// back button fix: when search backend click go or hot enter on term field,
		//it also sends db. this db should be same as dbconnector's db
		'SearchBarSearch' : function(sMessage, oData, sSrc){
			if (this.getValue("Db") != oData.db){
				this.setValue("Db", oData.db);
			}
		},
		
		// back button fix: whrn links is selected from DisplayBar,
		//ResultsSearchController sends the LastQueryKey from the results on the page
		'LastQueryKey' : function(sMessage, oData, sSrc){
			if (this.getInput("LastQueryKey")){
				this.setValue("LastQueryKey", oData.qk);
			}
		},
		
		//ResultsSearchController asks for the initial item count in case of send to file 
		'needSavedSelectedItemCount' : function(sMessage, oData, sSrc){
			var count = 0;
			if(this.getInput("IdsFromResult")){
				if (this.getValue("IdsFromResult").length > 0){
					count = this.getValue("IdsFromResult").split(',').length;
				}
				console.info("sending SavedSelectedItemCount from IdsFromResult: " + count);
			}
			else{
				count = Portal.Portlet.DbConnector.originalCount;
				console.info("sending SavedSelectedItemCount from OriginalCount: " + count);
			}
			this.send.SavedSelectedItemCount({'count': count});
		},
		
		// Force form submit, optionally passing db, term and cmd parameters
		'ForceSubmit': function (sMessage, oData, sSrc)
		{
		    if (oData.db)
    			this.setValue("Db", oData.db);
		    if (oData.cmd)
    			this.setValue("Cmd", oData.cmd);
		    if (oData.term)
    			this.setValue("Term", oData.term);
    		Portal.requestSubmit ();
		}
	}
},
{
	originalIdList: '',
	originalCount: 0
});

Portal.Portlet.SearchBar = Portal.Portlet.extend ({
  
	init: function (path, name, notifier) 
	{
		console.info ("Created SearchBar"); 
		this.base (path, name, notifier);

        Portal.Portlet.SearchBar.originalTerm = this.getValue("Term");
        Portal.Portlet.SearchBar.originalDb = this.getValue("Db");
	},

	// Define message sender methods here.
	// If you just want to send a message the standard way, simply
	// supply "null" as the implementation. 
	// 
	send: {
		"Cmd": null,
		"Term": null,
		"TabCmd": null,
		"DbChanged": null, 
		"SearchBarSearch": null
	},

	// Define messages and events
	listen: {

		// Global message bus
		'IndexLogicalOp': function(sMessage, oData, sSrc) {
			var sbTerm = this.getValue("Term");
			var oTerm = this.getInput("Term");
			var newValue = oData.key;

			console.info ("In Indexlogocalop in SearchBar");

			if (sbTerm != "") {
				newValue = sbTerm + ' ' + oData.op + ' ' + oData.key;
			}
			this.setValue("Term", newValue);
			if (oTerm) {
			   oTerm.focus();
			}
		},

		'TermLogicalOp': function(sMessage, oData, sSrc) {
			var sbTerm = this.getValue("Term");
			var bNotBlank = sbTerm != "";
			
			if (bNotBlank)
			   sbTerm = '(' + sbTerm + ') ' + oData.op + ' (';
			
			sbTerm += oData.key;
			
			if (bNotBlank)
			   sbTerm += ')';
	 
			this.setValue("Term", sbTerm);  
			this.send.Term({'term' : sbTerm});
			this.getInput("Term").focus();
		},

		'LimitsGoClicked': function(sMessage, oData, sSrc) {
			this.send.Cmd({
				'cmd' : this.getValue("Go:cmd")
			});
			this.send.Term({
				'term' : this.getValue("Term")
			});
			// for back button fix, when go is clicked, also send db in searchbar, for checking against dbconnector
			this.send.SearchBarSearch({
				'db' : this.getValue("Db")
			});
			Portal.requestSubmit();
		},

		'Cmd': function(sMessage, oData, sSrc) {
			if (oData.cmd == 'CommandTabClicked'){
				// for back button fix, when Tab is clicked, also send db in searchbar
				if (this.getValue("Db")){
					this.send.DbChanged({
						'db' : this.getValue("Db")
					});
				}
			}
		},
		
		'AppendTerm': function(sMessage, oData, sSrc) {
		    var newTerm = Portal.Portlet.SearchBar.originalTerm;
		    if (Portal.Portlet.SearchBar.originalTerm != '' && oData.op != ''){
		        newTerm += ' ' + oData.op + ' ';
		    }
		    newTerm += oData.term;
		    //this.setValue("Term", newTerm); 
			this.send.Term({'term': newTerm });
			// for back button fix, send original db
			this.send.SearchBarSearch({
				'db' : Portal.Portlet.SearchBar.originalDb
			});
		},
		
		'ClearSearchBarTerm': function(sMessage, oData, sSrc) {
			this.setValue("Term", '');
		}, 

		// Browser events
		"Term<keypress>": function(event, target, name) {
			event = event || utils.fixEvent (window.event);
			if ((event.keyCode || event.which) == 13) 
			{
				// Emulate Go command.
	    
				console.info ("In term keypress: CMD  in SearchBar");
				this.send.Cmd({'cmd' : this.getValue("Term:cmd") });

				// In History Tab, Term field should send command Preview
				if (this.getValue("Term:cmd") == 'Preview')
				{
					this.send.TabCmd({
						'tab' : this.getValue("Db:tab")
					});
				}
	    
				console.info ("In term keypress : TERM in SearchBar");
				this.send.Term({'term': this.getValue("Term") });

			    // for back button fix, when go is clicked, also send db in searchbar, for checking against dbconnector
			    this.send.SearchBarSearch({
				    'db' : this.getValue("Db")
			    });
            
				event.returnValue = false;
				if (event.stopPropagation != undefined)
                      event.stopPropagation ();   
				if (event.preventDefault != undefined)
                      event.preventDefault ();   
				Portal.requestSubmit (); 
				return false;
			}
		},
      
		// Cmd is set to Go, so ResultsView of other database can choose component based 
		// on value of Cmd. The existing search term is also passed down.
		"Go<click>": function(e, target, name) {
		 	this.send.Cmd({
				'cmd' : this.getValue("Go:cmd")
			});
		   	this.send.Term({
				'term' : this.getValue("Term")
			});
			// for back button fix, when go is clicked, also send db in searchbar, for checking against dbconnector
		 	this.send.SearchBarSearch({
				'db' : this.getValue("Db")
			});
		},
		

		"Preview<click>": function(e, target, name) {
		 	this.send.Cmd({
				'cmd' : 'Preview'
			});
		   	this.send.Term({
				'term' : this.getValue("Term")
			});
		   	this.send.TabCmd({
				'tab' : this.getValue("Preview:tab")
			});
			// for back button fix, when go is clicked, also send db in searchbar, for checking against dbconnector
		 	this.send.SearchBarSearch({
				'db' : this.getValue("Db")
			});
		},
	  
		// to indicate that the db field was the submitter, this will also set future 
		// TabCmd to current TabCmd and keep the existing search term.
		"Db<change>": function(e, target, name) {
		 	this.send.Cmd({
				'cmd' : this.getValue("Db:cmd")
			});
			console.info ("In DB SearchBar: " + this.getValue("Db:cmd"));
			this.send.TabCmd({
				'tab' : this.getValue("Db:tab")
			});
			this.send.DbChanged({
				'db' : this.getValue("Db")
			});
			this.send.Term({
				'term' : this.getValue("Term")
			});
		},
		
		// On Clear button click, set focus to search box and clear the term
		"Clear<click>": function (e, target, name) 
		{
		    this.setValue ("Term", "");
            var term = this.getInput ("Term");
            if (term) 
                term.focus (); 
		}
	}
},
{
	originalTerm: '',
	originalDb: ''
});


Portal.Portlet.Pubmed_SearchBar = Portal.Portlet.extend ({
  
	init: function (path, name, notifier) 
	{
		console.info ("Created SearchBar"); 
		this.base (path, name, notifier);

        Portal.Portlet.Pubmed_SearchBar.originalTerm = this.getValue("Term");
        Portal.Portlet.Pubmed_SearchBar.originalDb = this.getValue("Db");
	},

	// Define message sender methods here.
	// If you just want to send a message the standard way, simply
	// supply "null" as the implementation. 
	// 
	send: {
		"Cmd": null,
		"Term": null,
		"TabCmd": null,
		"DbChanged": null, 
		"SearchBarSearch": null
	},

	// Define messages and events
	listen: {

		// Global message bus
		'IndexLogicalOp': function(sMessage, oData, sSrc) {
			var sbTerm = this.getValue("Term");
			var oTerm = this.getInput("Term");
			var newValue = oData.key;

			console.info ("In Indexlogocalop in SearchBar");

			if (sbTerm != "") {
				newValue = sbTerm + ' ' + oData.op + ' ' + oData.key;
			}
			this.setValue("Term", newValue);
			if (oTerm) {
			   oTerm.focus();
			}
		},

		'TermLogicalOp': function(sMessage, oData, sSrc) {
			var sbTerm = this.getValue("Term");
			var bNotBlank = sbTerm != "";
			
			if (bNotBlank)
			   sbTerm = '(' + sbTerm + ') ' + oData.op + ' (';
			
			sbTerm += oData.key;
			
			if (bNotBlank)
			   sbTerm += ')';
	 
			this.setValue("Term", sbTerm);  
			this.send.Term({'term' : sbTerm});
			this.getInput("Term").focus();
		},

		'LimitsGoClicked': function(sMessage, oData, sSrc) {
			this.send.Cmd({
				'cmd' : this.getValue("Go:cmd")
			});
			this.send.Term({
				'term' : this.getValue("Term")
			});
			// for back button fix, when go is clicked, also send db in searchbar, for checking against dbconnector
			this.send.SearchBarSearch({
				'db' : this.getValue("Db")
			});
			Portal.requestSubmit();
		},

		'Cmd': function(sMessage, oData, sSrc) {
			if (oData.cmd == 'CommandTabClicked'){
				// for back button fix, when Tab is clicked, also send db in searchbar
				if (this.getValue("Db")){
					this.send.DbChanged({
						'db' : this.getValue("Db")
					});
				}
			}
		},
		
		'AppendTerm': function(sMessage, oData, sSrc) {
		    var newTerm = Portal.Portlet.Pubmed_SearchBar.originalTerm;
		    if (Portal.Portlet.Pubmed_SearchBar.originalTerm != '' && oData.op != ''){
		        newTerm += ' ' + oData.op + ' ';
		    }
		    newTerm += oData.term;
		    //this.setValue("Term", newTerm); 
			this.send.Term({'term': newTerm });
			// for back button fix, send original db
			this.send.SearchBarSearch({
				'db' : Portal.Portlet.Pubmed_SearchBar.originalDb
			});
		},
		
		'ClearSearchBarTerm': function(sMessage, oData, sSrc) {
			this.setValue("Term", '');
		}, 

		// Browser events
		"Term<keypress>": function(event, target, name) {
			event = event || utils.fixEvent (window.event);
			if ((event.keyCode || event.which) == 13) 
			{
				// Emulate Go command.
	    
				console.info ("In term keypress: CMD  in SearchBar");
				this.send.Cmd({'cmd' : this.getValue("Term:cmd") });

				// In History Tab, Term field should send command Preview
				if (this.getValue("Term:cmd") == 'Preview')
				{
					this.send.TabCmd({
						'tab' : this.getValue("Db:tab")
					});
				}
	    
				console.info ("In term keypress : TERM in SearchBar");
				this.send.Term({'term': this.getValue("Term") });

			    // for back button fix, when go is clicked, also send db in searchbar, for checking against dbconnector
			    this.send.SearchBarSearch({
				    'db' : this.getValue("Db")
			    });
            
				event.returnValue = false;
				if (event.stopPropagation != undefined)
                      event.stopPropagation ();   
				if (event.preventDefault != undefined)
                      event.preventDefault ();   
				Portal.requestSubmit (); 
				return false;
			}
		},
      
		// Cmd is set to Go, so ResultsView of other database can choose component based 
		// on value of Cmd. The existing search term is also passed down.
		"Go<click>": function(e, target, name) {
		 	this.send.Cmd({
				'cmd' : this.getValue("Go:cmd")
			});
		   	this.send.Term({
				'term' : this.getValue("Term")
			});
			// for back button fix, when go is clicked, also send db in searchbar, for checking against dbconnector
		 	this.send.SearchBarSearch({
				'db' : this.getValue("Db")
			});
		},
		

		"Preview<click>": function(e, target, name) {
		 	this.send.Cmd({
				'cmd' : 'Preview'
			});
		   	this.send.Term({
				'term' : this.getValue("Term")
			});
		   	this.send.TabCmd({
				'tab' : this.getValue("Preview:tab")
			});
			// for back button fix, when go is clicked, also send db in searchbar, for checking against dbconnector
		 	this.send.SearchBarSearch({
				'db' : this.getValue("Db")
			});
		},
	  
		// to indicate that the db field was the submitter, this will also set future 
		// TabCmd to current TabCmd and keep the existing search term.
		"Db<change>": function(e, target, name) {
		 	this.send.Cmd({
				'cmd' : this.getValue("Db:cmd")
			});
			console.info ("In DB SearchBar: " + this.getValue("Db:cmd"));
			this.send.TabCmd({
				'tab' : this.getValue("Db:tab")
			});
			this.send.DbChanged({
				'db' : this.getValue("Db")
			});
			this.send.Term({
				'term' : this.getValue("Term")
			});
		},
		
		// On Clear button click, set focus to search box and clear the term
		"Clear<click>": function (e, target, name) 
		{
		    this.setValue ("Term", "");
            var term = this.getInput ("Term");
            if (term) 
                term.focus (); 
		},
		
		// On Advanced Search click, clear the term field and set Cmd
		"AdvSearch<click>": function (e, target, name) 
		{	
		    if (this.getInput("Term") && this.getValue("Term") != ''){
		        target.href = target.href + "?term=" + encodeURIComponent(this.getValue("Term")); /* Term may contain special char */
		    }
		    
		   	window.location = target.href;			
		}
	}
},
{
	originalTerm: '',
	originalDb: ''
});

